셸: STDIN/STDOUT 두 명령을 서로 파이핑

셸: STDIN/STDOUT 두 명령을 서로 파이핑

POSIX 쉘을 사용하여 실행하면,

$ cmd0 | cmd1

cmd0의 STDOUT은 cmd1의 STDIN으로 파이프됩니다.

Q: 게다가 어떻게 해야 하나요?반품cmd1의 STDOUT을 cmd0의 STDIN으로 파이핑하시겠습니까?

명명된 파이프(FIFO)에서 강제로 리디렉션하시겠습니까? 나는 명명된 파이프가 일부 파일 시스템 경로를 차지하고 이름 충돌을 걱정해야 하기 때문에 그다지 좋아하지 않습니다. 아니면 C, Python 또는 일부 일반 프로그래밍 언어에서 파이프라인(2)을 호출해야 합니까?

(cmd0과 cmd1은 모두 일부 네트워크 I/O를 수행하므로 서로를 영원히 차단하지 않습니다.)

답변1

양방향 파이프가 있는 시스템(Linux가 아님)에서는 다음을 수행할 수 있습니다.

cmd0 <&1 | cmd1 >&0

Linux에서는 다음을 수행할 수 있습니다.

: | { cmd1 | cmd2; } > /dev/fd/0

이는 Linux(및 Cygwin이지만 일반적으로 다른 시스템은 아님)에서 /dev/fd/x파이프 x(이름이 지정되거나 지정되지 않은)에 대한 fd가 명명된 파이프처럼 작동하기 때문에 작동합니다. 즉, 읽기 모드에서 파이프를 열면 읽기 측을 얻고 쓰기 모드로 들어가면 너 글쓰기 끝이야.

와 함께yash껍데기그리고 그것의x>>|y 파이프 리디렉션운영자:

{ cmd0 | cmd1; } >>|0

그리고coproc을 지원하는 쉘:

  • 지쉬어:

       coproc cmd0
       cmd1 <&p >&p
    
  • 케시

       cmd0 |&
       cmd1 <&p >&p
    
  • bash4+

       coproc cmd0
       cmd1 <&"${COPROC[0]}" >&"${COPROC[1]}"
    

특수 도구 방법 (답변에서 뻔뻔하게 복사됨)이 매우 비슷한 질문):

사용pipexec

pipexec [ A /path/to/cmd0 ] \
        [ B /path/to/cmd1 ] \
        '{A:1>B:0}' '{A:0>B:1}'

또는 사용dpipe

dpipe cmd0 = cmd1

또는 사용socat:

socat EXEC:cmd0 EXEC:cmd1,nofork                 # using socketpairs
socat EXEC:cmd0,commtype=pipes EXEC:cmd1,nofork  # using pipes

잘 모르겠지만 python이 작업도 비교적 쉽게 수행할 수 있습니다 perl.

perl -e 'pipe STDOUT,STDIN; exec "cmd0 | cmd1"'

언제든지 명명된 파이프에 의지할 수도 있지만 고유한 이름과 이를 생성하기 위한 일부 보안 디렉터리를 찾고, 이에 대한 액세스를 제한하고(다른 프로세스가 파이프를 열거나 방해할 수 없도록) 나중에 정리하는 것은 추가적인 문제가 됩니다. 극복하기 어렵습니다. 신뢰성과 휴대성이 뛰어납니다.

어쨌든 교착상태에 주의하세요!

관련 정보