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전에 모든 출력을 쓸 수 있으면 head쓰기가 SIGPIPE를 트리거하지 않습니다.

또는 종료하기 전에 모든 출력을 기록하는 것이 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.

관련 정보