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

関連情報