| 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