이것은 명령입니다:
{ ( echo "to stdout"; echo "to stderr" >&2 ) > >(sleep 1; tee stdout.txt); } 2> >(sleep 2; tee stderr.txt >&2 )
이것이 내가 보는 것입니다:
다루기 힘든
% { ( echo "to stdout"; echo "to stderr" >&2 ) > >(sleep 1; tee stdout.txt); } 2> >(sleep 2; tee stderr.txt >&2 )
to stdout
to stderr
%
세게 때리다
$ { ( echo "to stdout"; echo "to stderr" >&2 ) > >(sleep 1; tee stdout.txt); } 2> >(sleep 2; tee stderr.txt >&2 )
$ to stdout
to stderr
bash는 출력이 완료되기 전에 프롬프트를 작성 $
하지만 zsh는 사용자에게 프롬프트를 표시하기 전에 교체 프로세스가 완료될 때까지 기다립니다 %
.
합리적인 대답은 "그게 zsh가 작동하는 방식이기 때문입니다"라고 생각합니다. 그러나 이것이 더 많은 것을 배울 수 있도록 어디에 문서화되어 있는지 알고 싶습니다. 많은 bash 사용자 중 zsh 사용자로서 저는 "이 명령을 실행해 보세요"라고 말하면 어떤 일이 발생하는지 알 수 있도록 차이점을 이해하려고 노력합니다.
답변1
더 짧은 예는 두 쉘 모두에서 동일한 방식으로 작동합니다. 상위 쉘은 기다리지 않습니다.
(sleep 1; echo done) > >(cat >file) &
다음과 같이 수정하면,zsh
~ 할 것이다잠깐만요. 하지만 bash
그렇지는 않습니다:
{ (sleep 1; echo done) & } > >(cat >file)
zshexpn(1)
유사한 예가 매뉴얼의 "PROCESS SUBSTITUTION"에 나와 있습니다. 거기 { ... }
에는 비동기 프로세스의 출력을 프로세스 대체(두 셸 모두에서 비동기임)로 리디렉션할 때 셸이 비동기 프로세스를 기다리지만 { ... }
.
설명서에는 문제가 다음과 같이 설명되어 있습니다.
>(process)
외부 명령에 연결하면 추가적인 문제가 발생합니다 .상위 셸은 프로세스가 완료될 때까지 기다리지 않으므로 뒤따르는 명령은 완료 결과에 의존할 수 없습니다..
비동기 명령을 복합으로 캡슐화함으로써 { ... }
"여기의 추가 프로세스는 상위 셸에서 생성되고 상위 셸은 완료될 때까지 기다립니다." 이에 대한 내 해석은 우리가 리디렉션하는 프로세스가 >(...)
셸에서 생성되는 반면, 그렇지 않은 프로세스는 { ... }
백그라운드 작업으로 시작한 작업에서 생성된다는 것입니다(그래서 셸은 이를 기다리지 않습니다).
$ZSH_SUBSHELL
리디렉션하는 프로세스 교체에서 출력을 가져오면 이에 대한 증거를 찾을 수 있습니다. 차단 코드의 경우 를 출력하고 1
, 비차단 코드의 경우 를 출력합니다. 이는 2
출력이 다른 하위 쉘 내에서 하위 쉘로 실행되도록 리디렉션됨을 나타냅니다(메인 쉘은 기다리지 않음).
출력 프로세스 교체의 출력이 에서와 동일한 동작을 나타내 더라도 쉘은 bash
이를 다르게 처리하고 두 경우 모두 상위 쉘과 독립적으로 모든 백그라운드 작업을 생성하는 것으로 보입니다 .$BASH_SUBSHELL
zsh