破損したパイプによってUnixプロセスが終了する原因は何ですか?

破損したパイプによってUnixプロセスが終了する原因は何ですか?

気に入ったいくつかのオプションは次のとおりです。どちらが正しいかわからない。

  1. パイプからの読み込み中にI / Oエラーが発生しました。
  2. パイプのもう一方の端に書き込むプロセスは失敗で終了します。
  3. パイプに書き込むことができるすべてのプロセスがパイプを閉じました。
  4. パイプの書き込みバッファがいっぱいです。
  5. ピアがデュアルパイプの別の方向を閉じました。
  6. パイプから読み取ることができるプロセスがないため、書き込みは失敗します。
  7. システムコールが EPIPE エラーを返し、エラーハンドラがインストールされていません。

ベストアンサー1

プロセスは、残りのリーダーを持たないタイプSOCK_STREAMのパイプ(名前が指定または指定されていない)またはソケットに書き込もうとするとSIGPIPEを受け取ります。

これは通常望ましい動作です。典型的な例は次のとおりです。

find . | head -n 1

find終了した後head(読み取るために開いていたそのパイプの唯一のファイル記述子を閉じた後)、実行を続けたくありません。

コマンドはyes通常、この信号に依存して終了します。

yes | some-command

「y」は、コマンドが終了するまで記録されます。

これは、コマンドが終了したときだけでなく、すべてのリーダーがパイプからfd読み取りを閉じるときにも発生します。存在する:

yes | ( sleep 1; exec <&-; ps -fC yes)
      1 2       1        0

サブシェルが明示的にstdinを閉じた後、パイプは1(サブシェル)、2(サブシェル+スリープ)、1(サブシェル)、0 fdの読み取りを受け取り、この時点でyesSIGPIPEを受け取ります。

上記では、ほとんどのシェルはpipe(2)whileをksh93使用しsocketpair(2)ますが、これに関して動作は同じです。

プロセスがSIGPIPEを無視すると、書き込みシステム呼び出し(通常はwrite、、pwrite... sendspliceがエラーを返しますEPIPE。したがって、破損したパイプを手動で処理しようとするプロセスは、SIGPIPEを無視し、EPIPEエラーに対して対処することがよくあります。

おすすめ記事