SIGPIPE 및 bash 파이프 실패

SIGPIPE 및 bash 파이프 실패

저는 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파이프를 종료하고 끊기 전에 모든 출력을 쓸 수 있습니다 . 이 때문입니다:lshead

  • head최종적으로 인쇄되는 것보다 더 많은 내용을 읽을 수 있습니다.
  • 어쨌든 파이프에 대한 버퍼가 있습니다.

SIGPIPE는 깨진 파이프에 실제로 쓰는 것에 의해 트리거됩니다. 종료하기 ls전에 모든 출력을 기록하는 경우 headSIGPIPE를 트리거하는 쓰기 작업이 없습니다.

또는 종료되기 ls전에 모든 출력을 기록하지 못할 수도 있습니다 head. 그런 다음 더 많은 쓰기를 시도하고 SIGPIPE를 얻습니다.

ls병렬로 실행하면 일반적 head으로 경쟁 조건이 있다고 생각합니다. 의 일부 특정 출력이 lsSIGPIPE를 무작위로 트리거하거나 트리거하지 않는 경우가 발생할 수 있습니다 .

yes다음 대신 사용해 보세요 ls ….

{ yes ; echo "$?" 1>&2 ; } | head

또는

( set -o pipefail; { yes ; echo "$?" 1>&2 ; } | head; )

yes자체적으로 끝나지 않는 출력을 생성하므로 head종료 후에는 항상 SIGPIPE를 트리거하는 쓰기 작업이 있습니다. 위의 각 명령을 사용하면 141확실하게 알 수 있습니다.

이것은 와는 아무 관련이 없습니다 pipefail.

관련 정보