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
。