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 で終了し続ける理由です。