다음 줄은 분명합니다.
echo "bla" | foo | bar
그런데 저 아래 사람들도 그렇게 합니까?
echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)
표준 입력에서 "bla"를 읽는 이유는 무엇입니까 foo
?bar
물론 코딩하고 확인할 수는 있지만 정의된 동작인지 아니면 의존해서는 안 되는 기능을 활용하고 있는지는 확실하지 않습니다.
답변1
이는 쉘에 따라 다르며 AFAICS에 문서화되어 있지 않습니다. ksh
및 에서 bash
첫 번째 경우에는 foo
동일한 표준 입력이 와 공유됩니다 bar
. 그들은 생산량을 위해 싸울 것입니다 echo
.
예를 들어,
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
paste
다른 텍스트 블록을 읽는 동안 의 출력에서 다른 모든 텍스트 블록을 읽는 증거를 볼 수 있습니다 .seq
tr
를 사용하면 zsh
외부 표준 입력을 얻습니다(터미널이 아니고 쉘이 대화형이 아닌 경우, /dev/null
터미널에서 cmd &
). ksh
(원산지) 프로세스 교체를 지원하는 유일한 Bourne 유사 셸입니다 zsh
.bash
에서는 stdin이 의 출력에서 제공되는 파이프라는 점에 echo "bla" | bar < <(foo)
유의하세요 . 이는 잘 정의된 동작입니다. 이 경우 stdin이 전부인 것처럼 보이고 파이프도 제공됩니다.bar
foo
foo
echo
ksh
zsh
bash
세 가지 셸 모두에서 일관된 동작을 원하고 동작이 문서화되지 않고 변경될 수 있으므로 미래에도 대비하고 싶다면 다음과 같이 작성합니다.
echo bla | { bar <(foo); }
확실히 foo
stdin도 파이프에서 나옵니다 echo
(하지만 왜 그렇게 하려는지 모르겠습니다). 또는:
echo bla | bar <(foo < /dev/null)
foo
확인하십시오아니요파이프에서 읽습니다 echo
. 또는:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
foo
의 현재 버전과 같은 Make 의 stdin 외부 표준 입력입니다 zsh
.
답변2
echo "bla" | foo | bar
: 의 출력은 echo "bla"
로 리디렉션 foo
되고 해당 출력은 로 리디렉션됩니다 bar
.
echo "bla" | bar <(foo)
: 출력 echo "bla"
을 bar
. 하지만 bar
매개변수를 사용하여 실행됩니다. 인수 foo
는 출력이 전송될 파일 설명자의 경로입니다 . 이 매개변수는 다음과 같이 동작합니다 foo
.그건 달라.
echo "bla" | bar < <(foo)
: 출력이 다음 echo "bla"
으로 전송되어야 하며 bar
전체 명령문이 첫 번째 명령문과 동일하다고 가정할 수 있습니다. 그러나 이것은 잘못된 것입니다. 다음과 같은 일이 발생합니다.입력 리디렉션은 <
파이프( |
) 이후에 수행되므로 덮어쓰게 됩니다.. 그래서 echo "bla"
바에는 파이프로 연결된 것이 없습니다. 대신 출력이 foo
표준 입력으로 리디렉션됩니다 bar
. 이 문제를 해결하려면 다음 명령 및 출력을 참조하세요.
$ echo "bla" | cat < <(echo "foo")
foo
보시다시피 echo "bla"
교체되었습니다 echo "foo"
.
이제 다음 명령을 살펴보세요.
$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo
그래서 echo "bar"
파이프로 연결하면 awk
stdin을 읽고 문자열을 and foo
출력에 추가합니다. 이 출력은 cat
.