zsh: 명령 대체는 상위 항목으로부터 표준 입력을 상속받지 않습니다.

zsh: 명령 대체는 상위 항목으로부터 표준 입력을 상속받지 않습니다.

다음 명령을 고려하십시오.

seq 5 | grep $(tail -n1) <(seq 9)

zsh1 에서 실행할 때 :

tail: error reading 'standard input': Input/output error

이제 에서 동일한 작업을 실행하면 bash다음과 같이 출력됩니다.

5

좋아요 주석에 설명된 대로 명령 대체는 상위 항목에서 $(tail -n1)상속됩니다 . stdin그런데 왜 이런 일이 일어나지 않습니까 zsh?
이것이 zsh유일한 것입니까, 아니면 다른 쉘도 이것을합니까? 어디에 기록되어 있나요?


이제 다음을 통해 동일한 명령을 실행하면 zsh -c:

zsh -c 'seq 5 | grep $(tail -n1) <(seq 9)'

동일한 오류 메시지를 인쇄하는 대신 중지 tail -n1하고 사용자 입력을 기다리므로 다음을 입력하면 됩니다.

19
2
4

Ctrl그런 다음 +를 누르면 D인쇄됩니다.

4

여기서 무슨 일이 일어나고 있는 걸까요?


1: 중요하다면 이것은 zsh 5.3.1on입니다.archlinux

답변1

당신은 알게 될 것입니다 bash/ksh

echo foo | echo "$(cat)"

출력 foo하지만

<<< foo echo "$(cat)"

아니요.

첫 번째 경우, 표준 입력이 파이프에서 리디렉션된 후 $(cat)최종적으로 실행될 하위 프로세스에서 해제합니다 .echo

두 번째 경우에는 $(cat)리디렉션하기 전에 확장하세요.

파이프와 리디렉션은 서로 다릅니다. 파이프라인에는 일부가 포함됩니다.리디렉션명령을 병렬로 실행하는 것도 가능합니다. 이는 각 파이프라인 구성 요소 내부 리디렉션 전에 발생합니다.

존재하다zsh

$ sleep 1 | ps -jfH $(ps -fH >&2)
UID        PID  PPID  C STIME TTY          TIME CMD
chazelas  2495  2494  0 20:59 pts/1    00:00:00 /bin/zsh
chazelas 31201  2495  0 21:20 pts/1    00:00:00   sleep 1
chazelas 31202  2495  0 21:20 pts/1    00:00:00   ps -fH
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
chazelas  2495  2494  2495  2495  0 20:59 pts/1    00:00:00 /bin/zsh
chazelas 31201  2495 31201  2495  0 21:20 pts/1    00:00:00   sleep 1
chazelas 31203  2495 31201  2495  0 21:20 pts/1    00:00:00   ps -jfH

이번에는 명령 대체가 상위 셸에 의해 확장되었음을 알 수 있습니다.

명심해야 할 한 가지는 에서 파이프는 특히 옵션(기본적으로 활성화되어 있음) zsh과 관련하여 리디렉션처럼 취급된다는 것입니다.mult_ios

이 작업을 수행할 때:

echo foo > file | tr o e

foofile및 로 이동합니다 tr.

존재하다:

uname | cat < /etc/issue

cat입력되는 출력 합계 uname의 내용입니다 /etc/issue. 따라서 에서는 zsh파이프라인으로/에서 파이프라인으로의 리디렉션이 동일한 단계에서 발생해야 합니다. 확장 후 사용하는 것이 좋습니다.<>

어쨌든 언제든지 다음과 같이 할 수 있습니다.

echo foo | { echo "$(cat)"; }

in zshbash/ ksh언제나 그렇듯:

{ echo "$(cat)"; } <<< foo

및 .bashzsh


이유는 다음과 같습니다.

tail: error reading 'standard input': Input/output error

실수. 대화형 쉘에서는 명령 대체가 상위 프로세스에서 수행되므로 터미널의 포그라운드 프로세스 그룹에서는 수행되지 않습니다.

tail상위 쉘의 프로세스 그룹에서 실행됩니다. 쉘이 세션 리더라면,고아 프로세스 그룹, 따라서 tailtty 장치에서 읽으려고 하면 EIO로 인해 실패합니다.

zsh회의 주최자가 아닌 경우 . 예를 들어, 다른 쉘에서 시작하면 zsh프로세스 그룹은 SIGTTIN을 받게 됩니다. 기본 셸 프로세스는 이를 무시하지만 tail결국 중단됩니다.

관련 정보