パイプを介して尾にコマンドを送信する:最初のコマンドはいつ中断されますか?

パイプを介して尾にコマンドを送信する:最初のコマンドはいつ中断されますか?

この例では、次のようになります。

$ for i in {1..3}; do sleep 1; echo $i;  done | head -n 2

最初のコマンド(forループ)が3表示の直前に終了するのはなぜですか?私はそれが2見られるとすぐに殺されると予想した。

最初に解決しようとした問題は次のとおりです。

$ for i in *(/); do c=`find "$i" -iname "*.ext" | wc -l`; echo "$c  $i"; done | head -n 3

画面に3行が浮かんだらすぐ終わると思っていましたが、4回ループを回しながら4行を捨てました。

私が起こると思ったこと:

sleep 1
echo 1
sleep 1
echo 2 
# 2 is printed and the for loop is killed

実際に起こったこと:

sleep 1
echo 1
sleep 1
echo 2 
sleep 1
echo 3
# 3 is not printed and the for loop is killed

ループ自体の内部にいくつかのロジックを追加せずに、指定された繰り返し回数の後にループをすぐに中断する方法はありますか?

ベストアンサー1

私の他のシェル(ksh、zsh、bash)には予想される動作があります。 3ではなく1、2のみです。ここでの問題は、ZSHバージョンでSIGPIPEがどのように処理されるかに関連している可能性があります。

「環境のない」インスタンスを使用してこれらのコマンドを実行できますか?たとえば、エイリアス、構成などはありません。

コメントで述べたように、シェルがwrite()関数を使用して何かをエコーし​​ようとするとエラーが発生します。パイプラインチェーン全体が実行されている限り(プロセスheadは実行中であり、STDINは開いています)すべてが正常です。しかし、head終了すると、シェルの出力はどこにも行きません(壊れたパイプ)。

ただし、シェルが標準出力に何かを書き込もうとするまで、パイプが壊れていることを知らずに処理を続けます。

したがって、デバッグに「echo 3」と表示され、これは失敗し、シェルを終了します。

おすすめ記事