백그라운드 프로세스 파이프 입력


14

화면에 "aaa"를 표시하려는 경우 :

(1)$: echo aaa | cat                 ... works OK
(2)$: echo aaa | ( cat )             ... works OK
(3)$: echo aaa | ( cat & )           ... NOT working
(4)$: ( echo aaa & ) | cat           ... works OK 
(5)$: echo aaa | ( cat <&0 & )       ... works ok in BASH (but not in SH)
(6)$: echo aaa | ( cat <&3 & ) 3<&0  ... works ok in BASH and SH

(3)과 (4)의 결론-> 분리 된 프로세스는 여전히 제어되고, 사용되며, 리디렉션 될 수 있지만 입력은 할 수없는 출력을 연결했습니다!

내 질문은 : 누군가가 왜 (5) 줄이 작동하는지 이해합니까 ?

... "<& 0"은 "0 <& 0"의 줄임말로, 0을 0으로 재지 정하는 것이 해결책이며 분리 된 프로세스의 입력으로 실제로 발생하는 결과입니다. 서브 쉘은 문제가되지 않으며, (...) 대신 중괄호 {...}를 사용하면 동일한 결과를 얻을 수 있습니다.

... 및 질문 2 : 라인 (6)보다 "분리 된 프로세스에 입력 제공"에 대한 더 나은 솔루션이 있습니까?

답변:


12

예, POSIX에 필요한대로 백그라운드에서 시작된 명령은 &표준 입력이에서 리디렉션되었습니다 /dev/null.

그리고 실제로

{ cmd <&3 3<&- & } 3<&0

이를 해결하는 가장 확실한 방법입니다.

왜 백그라운드에서 파이프 라인의 일부를 실행하고 싶은지 명확하지 않습니다.


이유는 파이프 체인 (cmd1 | {cmd2 &; pid2 = $ !;} | cmd3 ...) 내에서 하나의 특정 명령의 PID를 가져 오는 것이기 때문에 / dev / null == & 0이 BG 프로세스의 표준입니다. 이유도 아십니까 "0 <& 0"은 bash에서 작동하며 안전합니까?
Asain Kujovic

3
@OmerMerdan POSIX는 모든 경우에 표준 입력의 명시 적 리디렉션이 위의 내용과 모순되는 이 활동을 무시해야 하므로 리디렉션 bash을 취소하는 것으로 해석합니다 (그리고 합리적인 해석처럼 들립니다) /dev/null. 이제는 많은 쉘이 똑같이하지 않습니다. 애쉬와 pdksh는 그렇지 않습니다.
Stéphane Chazelas

3<&-부품이 필요하고 사용하기에 안전합니까 (전체 입력 IR 읽기 전에 파이프를 닫지 않습니까)?
mvorisek

1
@Mvorisek, fd 3는 원래 stdin을 복원하기 위해 일시적으로 만 사용됩니다. cmd필요하지 않으므로 닫습니다 . 우리는 그것을 fd 0에 담근 후에 닫습니다 ( <&3약칭 0<&3).
Stéphane Chazelas

1
@Mvorisek nohup은 stdin을 / dev / null로 리디렉션하므로 다음이 필요 { nohup sh -c 'cmd <&3 3<&-' & } 3<&0합니다.. 또는(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.