一部のプログラムでは、実行時間が無制限で出力が無制限である場合があります。完了コマンドと一緒にパイプライン内で使用されるとき、パイプラインはいつ停止する必要があるかをどうやって知ることができますか?
たとえば、yes
(無限出力)を使用すると、次のようになりますhead
。
yes | head -n 5
5つだけが生産されますy
。
終了する最初のコマンドは、他のプロセスの入出力を停止するコマンドですか?
どのように動作しますか?
答え1
このコマンドはパイプを介して接続されています(ここではシステムの基本要素について話しています。明らかにを通して接続されています|
)。パイプの読み取り終了(stdin
of )がd(==明示的に()または暗黙的に(終了)閉じている場合)、書き込み終了(of)への書き込み試行は失敗します。head
close
head
close
stdout
yes
デフォルトでは、これは単純なerrno
エラーではなく、書き込みプロセスが信号を受信する原因となるエラーですSIGPIPE
。基本ハンドラの操作SIGPIPE信号終了します。
簡単に言えば、破損したパイプに書き込むと、システムはあなたにaを送り、SIGPIPE
基本的にaはSIGPIPE
あなたを殺します。これが最後にyes
終了する理由ですhead
(したがってパイプが破壊されます)。
親シェルからこれを省略すると、コマンドがこのSIGPIPE
構成を継承し、write
壊れたパイプを呼び出すと、このエラーが文字列化され、次のように印刷されますerrno
。EPIPE
yes
$ (trap "" SIGPIPE; yes | head -n 5)
y
y
y
y
yes: standard output: Broken pipe
yes: write error