この例では、次のようになります。
$ 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」と表示され、これは失敗し、シェルを終了します。