読み取り、grep、パイプ、ハングアップ中

読み取り、grep、パイプ、ハングアップ中
yes "test" | grep -m3 "test"

プリント

test
test
test

そして終了します。

yes "test" | while read line; do echo $line; done | grep -m3 "test"

そして

yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"

しかし

yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"

プリント

test
test
test

そしてハングします。ここで何が起こっているのでしょうか?

答え1

yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"
4 つのプロセスがあり、それぞれ、、そのループyesを実行しているシェル プログラム、、を実行しています。パイプラインの最後のプロセスは、3 つの一致の後に、入力パイプの読み取り側を閉じて終了します。その後、パイプラインは、パイプラインの各ステージが壊れたパイプに書き込むことになるため、通常、途中で終了するパイプラインと同じように、一連の によって終了します。whilegrepgrepSIGPIPE

yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"
3つのプロセスがそれぞれ実行されています。yesシェルプログラム、およびgrep。しかし、2番目のプロセス、つまりシェルプログラムを実行しているプロセスは、継続的に2つのさらに遠く子プロセスがあり、1つは を実行しecho、もう1つは別のgrepインスタンスを実行します。後者のプロセスに が送信されSIGPIPEないシェル プログラムを実行しているプロセス。結局のところ、壊れたパイプに実際に書き込むのは後者のプロセスです。

その結果、パイプラインの2番目のステージであるwhileループを実行するシェルは、自体で終了しSIGPIPE、実行を継続し、子パイプラインを何度も生成します。生成された子パイプラインは当然終了するのですが、ループSIGPIPEを実行しているシェルにとってはwhileないループを終了する理由。

関連情報