다음 파이프가 있다고 가정하십시오.
a | b | c | d
어떻게 완료 기다릴 수 c
(나 b
)에서 sh
나 bash
? 즉, 스크립트 d
는 언제든지 시작할 수 있으며 (대기 할 필요 는 없지만 ) c
제대로 작동 하려면 전체 출력이 필요 합니다.
유스 케이스 는 이미지를 비교 하기 difftool
위한 것 git
입니다. 호출되어 git
입력 ( a | b | c
부분) 을 처리하고 비교 결과 ( 부분)를 표시해야합니다 d
. 발신자는 a
및에 필요한 입력을 삭제합니다 b
. 즉, 스크립트에서 돌아 오기 전에 프로세스 c
(또는 b
)를 종료해야합니다. 반면에, 나는 d
사용자 입력을 기다리고 있음을 의미 하기 때문에 기다릴 수 없습니다 .
c
임시 파일에 결과를 쓰거나에서 FIFO를 사용할 수 있음을 알고 있습니다 bash
. (FIFO가 도움이 될지 확실하지 않습니다.) 임시 파일없이이 작업을 수행 할 수 sh
있습니까?
편집하다
아마도 c
(또는 b
) 프로세스 의 프로세스 ID를 신뢰할 수있는 방식으로 찾을 수 있다면 충분할 것 입니다. 그런 다음 전체 파이프를 비동기식으로 시작할 수 있으며 프로세스 ID를 기다릴 수 있습니다. 라인을 따라 뭔가
wait $(a | b | { c & [print PID of c] ; } | d)
수정 ^ 2
해결책을 찾았으며 의견 (또는 여전히 더 나은 해결책)을 환영합니다.
답변
a | b | { c; [notify];} | d
예를 들어 환경 변수 ( kill -USR1 $EXTPID
) 로 전달 된 PID에 대한 신호 또는 파일 ( touch /path/to/file
) 을 생성하여 알림을 수행 할 수 있습니다 .
또 다른 아이디어 :
파이프 라인에서 다음 프로세스 (기다릴 수있는 프로세스)를 실행합니다.
a | b | { c; exec >&-; nextprocess;} | d
또는
a | b | { c; exec >&-; nextprocess &} | d
답변
귀하의 질문을 올바르게 이해하면 다음과 같이 작동합니다.
a | b | c | { (exec <&3 3<&-; d) &} 3<&0
fd 3 트릭은 (대부분의) 일부 쉘이 stdin을 / dev / null로 리디렉션하기 때문 &
입니다.
답변
답변
이것은 Hauke의 입력을 통해 시행 착오에서 찾은 것입니다.
a | b | { c; kill -PIPE $$; } | d
동등하게 :
a | b | ( c; kill -PIPE $$; ) | d
(후자는 {}
파이프 내부의 경우 어쨌든 서브 쉘에서 실행 되기 때문에보다 명확 합니다.)
(비롯한 몇몇 다른 신호 QUIT
, TERM
및 USR1
작업)도 있지만,이 경우에는 신호의 설명은 단말기에 표시된다.
이것이 PIPE
신호 의 원래 의도인지 궁금합니다 . 매뉴얼 에 따르면 :
SIGPIPE
:PIPE
프로세스가 다른 쪽 끝에 연결되지 않고 파이프에 쓰려고 할 때 신호가 프로세스로 전송됩니다.
즉, 인위적으로 파이프 신호를 서브 쉘에 보내면 자동으로 종료되어 최종 소비자 ( d
) 만 남게됩니다.
이것은 모두에서 작동 sh
하고 bash
.
답변
sponge
“moreutils”패키지에서 프로그램을 사용할 수 있습니다 .
a | b | c | sponge | d
스폰지는 c
배관하기 전에 출력 이 끝날 것입니다 d
. 그것이 당신이 원하는 희망입니다.
답변
당신은 할 수 있습니다 :
a | b | c | (d ; cat > /dev/null)
따라서 d
완료되면는 끝날 때까지 cat
나머지 c
출력을 흡수합니다 .
확인. 의견 후, 대답은 d
백그라운드에서 직접 시작 하는 것입니다.
하다:
a | b | c | (d &)
stdin 에서 읽는 데 문제가있는 경우 Stephane Chazelas 의 솔루션을 사용하십시오 .d