배쉬 : 프로세스 대체 및 표준 입력


13

다음 줄은 분명합니다.

echo "bla" | foo | bar

그러나 아래의 것들도 동일합니까?

echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)

의 어떤 foobarstdin을 왜에서 "즐"를 읽어?

물론 코드를 작성하고 확인할 수는 있지만 동작이 정의되어 있는지 또는 내가 의존해서는 안되는 기능을 활용하고 있는지 확실하지 않습니다.

답변:


9

셸에 따라 다르며 AFAICS는 문서화되어 있지 않습니다. 에서 kshbash의 첫 번째 경우 foo와 동일한 stdin을 공유합니다 bar. 그들은 출력을 위해 싸울 것입니다echo .

예를 들어

$ seq 10000 | paste - <(tr 1 X)'
1       X
2       X042
3       X043
4       X044
5       X045
[...]

paste다른 모든 텍스트 블록 을 읽는 증거를 볼 수 있습니다.seqtr읽는 동안의 출력 됩니다.

을 사용 zsh하면 외부 stdin을 얻습니다 (터미널이 아니며 쉘이 대화 형이 아닌 경우에는에서 리디렉션됩니다 /dev/null). ksh(원산지),zshbash만 Bourne의 형상 프로세스 AFAIK 교체를 지원하는 쉘.

에서는 echo "bla" | bar < <(foo)주 것을 bar의 표준 입력을 출력으로 공급 배관 것이다 foo. 그것은 잘 정의 된 행동입니다. 이 경우, 그 표시 foo의 표준 입력에 의해 공급 파이프이다 echo의 모두가 ksh, zsh그리고 bash.

세 가지 셸에서 일관된 동작을 원하고 동작이 문서화되지 않아 변경 될 수 있기 때문에 미래에 대비하려면 다음과 같이 작성하십시오.

echo bla | { bar <(foo); }

확실히 foo의 표준 입력으로부터도 파이프입니다 echo(당신이 생각을 할 싶어 내가 왜 볼 수 없습니다). 또는:

echo bla | bar <(foo < /dev/null)

하려면 확실히 foo않습니다 하지 에서 파이프에서 읽을 echo. 또는:

{ echo bla | bar 3<&- <(foo <&3); } 3<&0

foo현재 버전에서와 같이 외부 stdin을 stdin 하려면 zsh.


"이 경우, foo의 stdin은 모든 ksh, zsh 및 bash에서 echo에 의해 공급되는 파이프입니다." 지금 손으로 직접 테스트했거나 문서화되어 있습니까?
etam1024

첫 번째 줄의 "첫 번째 경우"는`| foo | 바`또는`| 바 <(foo)`?
Volker Siegel

4

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"파이프됩니다 awkstdin을 읽고 문자열을 추가하는 and foo출력에. 이 출력은로 파이프됩니다 cat.


그리고 제 질문은 awk""막대 " 를 읽는 것이 정의 된 행동입니까?"입니다.
etam1024

그렇습니다. cmd1 < <(cmd2)와 동일하게 작동합니다 cmd2 | cmd1.
카오스

또는cmd1 | cmd2 | cmd3cmd1 | cmd3 < <(cmd2)
카오스

3
그것이 위키 백과 인 경우 나는 당신의 진술에 "인용 필요"태그를 넣을 것입니다 :) 내 질문의 요점은 당신이 말한대로 작동한다는 것입니다.
etam1024
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.