while true; do
case $RANDOM in *0) exit 27 ;; esac
done
それともこんな感じ?
rc=0
for file in *; do
grep fnord "$file" || rc=$?
done
exit $rc
本当の問題は、1 回の繰り返しが失敗した場合に、ループの終了コードを成功にするか失敗にするかを決定することです。一方が他方よりも理にかなっているシナリオもあれば、まったく明確でないシナリオもあります。
ループのステータスは、実行された最後のコマンドのステータスです。 break を使用してループから抜け出すことができますが、ブレークが成功した場合、ループのステータスは 0
になります。 .ただし、サブシェルを使用して、中断する代わりに終了することができます。つまり:
for i in foo bar; do echo $i; false; break; done; echo $? # The loop succeeds
( for i in foo bar; do echo $i; false; exit; done ); echo $? # The loop fails
ループを関数に入れ、そこから値を返すこともできます。例:
in() { local c="$1"; shift; for i; do test "$i" = "$c" && return 0; done; return 1; }
bash のマニュアルには次のように書かれています:
while list-1; do list-2; done
until list-1; do list-2; done
[..]The exit status of the while and until commands is the exit status
of the last command executed in list-2, or zero if none was executed.[..]
内部で実行される最後のコマンド ループは break
です .そして break
の終了値 0 (参照:help break
).
これが、プログラムが 0 で終了し続ける理由です。