パイプラインはいつ停止する必要があるのか​​をどうやって知ることができますか?

パイプラインはいつ停止する必要があるのか​​をどうやって知ることができますか?

一部のプログラムでは、実行時間が無制限で出力が無制限である場合があります。完了コマンドと一緒にパイプライン内で使用されるとき、パイプラインはいつ停止する必要があるかをどうやって知ることができますか?

たとえば、yes(無限出力)を使用すると、次のようになりますhead

 yes | head -n 5

5つだけが生産されますy

終了する最初のコマンドは、他のプロセスの入出力を停止するコマンドですか?
どのように動作しますか?

答え1

このコマンドはパイプを介して接続されています(ここではシステムの基本要素について話しています。明らかにを通して接続されています|)。パイプの読み取り終了(stdinof )がd(==明示的に()または暗黙的に(終了)閉じている場合)、書き込み終了(of)への書き込み試行は失敗します。headcloseheadclosestdoutyes

デフォルトでは、これは単純なerrnoエラーではなく、書き込みプロセスが信号を受信する原因となるエラーですSIGPIPE。基本ハンドラの操作SIGPIPE信号終了します。

簡単に言えば、破損したパイプに書き込むと、システムはあなたにaを送り、SIGPIPE基本的にaはSIGPIPEあなたを殺します。これが最後にyes終了する理由ですhead(したがってパイプが破壊されます)。


親シェルからこれを省略すると、コマンドがこのSIGPIPE構成を継承し、write壊れたパイプを呼び出すと、このエラーが文字列化され、次のように印刷されますerrnoEPIPEyes

$ (trap "" SIGPIPE; yes | head -n 5)  
y
y
y
y
yes: standard output: Broken pipe
yes: write error

関連情報