| while readはbashプログラミングにおいてもっとも使われるイディオムのひとつですが、__このwhileループを脱出する際はbreakではなくexitを使います。__これはwhileがサブシェルになる影響――すなわちwhileから脱出するにはサブシェルを抜ける必要があります。
cat ${file} | while read line; do
[[ "${line}" = "END" ]] && exit 0
done
シェルコマンドは終了ステータスを持ち、whileは通常0を返しますが、exitを明示した場合にはそのexitの引数が終了ステータスになります。以下のサンプルに示すように、この性質は多重ループの脱出などに利用すると便利です。ただし以下のサンプルでは-eオプション、つまり0以外の終了ステータスを検知するとシェル自体を終了してしまうオプションは利用できなくなります。
echo ${files[@]} | while read file; do
cat ${file} | while read line; do
[[ "${line}" = "END" ]] && exit 99
done
[[ $? -eq 99 ]] && exit 99
done
whileループ脱出にexitを利用するのは、パイプの流し込み先にwhileが指定されたときだけです。つまり単なるwhileループの脱出にはbreakを利用します。exitを利用すると、当然ですがシェル自体が終了してしまい、想定通りの動作を示しません。
while :; do
do_something
[[ $? - ne 0 ]] && break
done