![SIGPIPE 및 bash 파이프 실패](https://rvso.com/image/231080/SIGPIPE%20%EB%B0%8F%20bash%20%ED%8C%8C%EC%9D%B4%ED%94%84%20%EC%8B%A4%ED%8C%A8.png)
저는 Linux에서 SIGPIPE를 더 잘 이해하려고 노력하고 있습니다.
나는 이 실험을 실행했습니다. { ls -al /tmp/ ; echo "$?" 1>&2 ; } | head
그리고 141
내가 이해하는 것은 종료 코드가 다음으로 종료되는 프로세스에 제공되는 종료 코드라는 것입니다. SIGPIPE
이전에는 의 뉘앙스를 이해하지 못한 채 이 작업을 많이 수행했고 SIGPIPE
일반적으로 set -eEuo pipefail
그렇게 실행했습니다. 파이프가 끊어져서 코드가 항상 실패하는 것은 아니었습니다... 그래서 다른 실험을 실행했습니다. ( set -o pipefail; { ls -al /tmp/ ; echo "$?" 1>&2 ; } | head; )
그 당시 에코에 0이 표시되었습니다... 그래서 pipefail
활성화되면 그것이 SIGPIPE
억제된다는 의미입니까? 아니면 여기서 무슨 일이 일어나고 있는지 오해하고 있습니까?
답변1
ls
의 출력이 인쇄 된 것보다 길더라도 head
파이프를 종료하고 끊기 전에 모든 출력을 쓸 수 있습니다 . 이 때문입니다:ls
head
head
최종적으로 인쇄되는 것보다 더 많은 내용을 읽을 수 있습니다.- 어쨌든 파이프에 대한 버퍼가 있습니다.
SIGPIPE는 깨진 파이프에 실제로 쓰는 것에 의해 트리거됩니다. 종료하기 ls
전에 모든 출력을 기록하는 경우 head
SIGPIPE를 트리거하는 쓰기 작업이 없습니다.
또는 종료되기 ls
전에 모든 출력을 기록하지 못할 수도 있습니다 head
. 그런 다음 더 많은 쓰기를 시도하고 SIGPIPE를 얻습니다.
ls
병렬로 실행하면 일반적 head
으로 경쟁 조건이 있다고 생각합니다. 의 일부 특정 출력이 ls
SIGPIPE를 무작위로 트리거하거나 트리거하지 않는 경우가 발생할 수 있습니다 .
yes
다음 대신 사용해 보세요 ls …
.
{ yes ; echo "$?" 1>&2 ; } | head
또는
( set -o pipefail; { yes ; echo "$?" 1>&2 ; } | head; )
yes
자체적으로 끝나지 않는 출력을 생성하므로 head
종료 후에는 항상 SIGPIPE를 트리거하는 쓰기 작업이 있습니다. 위의 각 명령을 사용하면 141
확실하게 알 수 있습니다.
이것은 와는 아무 관련이 없습니다 pipefail
.