반 비동기식 파이프 전에 프로세스

다음 파이프가 있다고 가정하십시오.

a | b | c | d

어떻게 완료 기다릴 수 c(나 b)에서 shbash? 즉, 스크립트 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로 리디렉션하기 때문 &입니다.


답변

bash에서는 프로세스 대체를 사용할 수 있습니다 . 프로세스 대체의 명령이 비동기 적으로 실행되며 대기하지 않습니다.

a | b | c > >(d)


답변

이것은 Hauke의 입력을 통해 시행 착오에서 찾은 것입니다.

a | b | { c; kill -PIPE $$; } | d

동등하게 :

a | b | ( c; kill -PIPE $$; ) | d

(후자는 {}파이프 내부의 경우 어쨌든 서브 쉘에서 실행 되기 때문에보다 명확 합니다.)

(비롯한 몇몇 다른 신호 QUIT, TERMUSR1작업)도 있지만,이 경우에는 신호의 설명은 단말기에 표시된다.

이것이 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


답변