Bash 셸에서 다음 예를 고려하세요.
$ echo 'test' | wc -c
5
모든 것이 예상대로 작동합니다. 이제 우리는 그것을 다음과 같이 바꿉니다.
$ echo 'test' >&0 | wc -c
test
0
이제 0
출력 내용이 완벽하게 이해됩니다. echo
모든 것이 (전통적으로 쓰기 가능)로 전송되었지만 stdin
로 아무것도 전송되지 않았 stdout
으므로 아무것도 파이프로 전달되지 않았습니다 wc
. 하지만 출력은 콘솔에 어떻게 표시됩니까? 이 test
줄은 누가 언제 인쇄했습니까?
마지막으로 세 번째 테스트(지원되는 플랫폼의 경우 stdbuf
)
$ stdbuf -i0 -o0 -e0 echo 'test' >&0 | wc -c
0
test
여기서 무슨 일이 일어나고 있는 걸까요? 순서가 왜 바뀌었나요?
답변1
은 터미널에 연결되므로 실행하면 출력이 stdin
터미널로 이동합니다. 일반적으로 표준 입력은 사용되지 않지만 예를 들어 존재합니다. 반면에 실행하면 두 번째 stdin에 연결된 파이프가 읽기 전용이기 때문에 "잘못된 파일 설명자" 오류가 발생합니다.echo
echo 'test' >&0
echo
cat
echo foo | echo test >&0
echo
stdbuf
다른 코드 조각에서는 파이프가 닫혀 있다는 사실을 알아차리는 것(아무도 파이프에 쓸 수 없도록 쓰기 쪽을 리디렉션함)과 터미널에 쓰는 것 사이에 경쟁이 있다고 생각합니다 . 이는 버퍼링과 아무 관련이 없으며(어쨌든 완료되면 버퍼를 플러시해야 하기 때문에 실제로 중요하지 않습니다) 또는를 사용하여 동일한 결과를 얻을 수 있습니다. 시작 속도를 늦추는 왼쪽의 모든 것이 영향을 미칩니다. 또한 을 사용하면 셸의 내장 구현을 실행할 수 있는 반면, 또는 을 사용하면 외부 구현을 실행한다는 점을 명심하세요. 더 빠르게 내장되어 있습니다.wc
stdin
echo
echo
strace echo ...
env echo ...
echo
echo | wc
echo
stdbuf
env
strace
echo
일반적으로 말하면 두 프로세스가 동시에 어딘가에 쓰는 경우 명시적으로 동기화되지 않는 한 쓰기 순서에 대해 어떤 가정도 할 수 없습니다.