
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 つの一致の後に、入力パイプの読み取り側を閉じて終了します。その後、パイプラインは、パイプラインの各ステージが壊れたパイプに書き込むことになるため、通常、途中で終了するパイプラインと同じように、一連の によって終了します。while
grep
grep
SIGPIPE
で
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
ないループを終了する理由。