bashはwhile内の処理が子プロセス扱いになる

bashは、while文の中でexitを実行してもシェル自体は終了せず、whileを抜けるだけになる。
while内は小プロセスとして扱われるらしい。
サンプルコードは以下。

#!/bin/bash

cat << END >> animal_list
cat
dog
alligator
END

cat animal_list | while read animal
do
    echo $animal

    if [ $animal = "dog" ]; then
        echo "中断!"
        exit 1
    fi
done

echo "だが終わってない"

exit 0

上記コードを実行するとこうなる。

cat
dog
中断!
だが終わってない

なので、中断したい場合はwhileを抜けた後に、以下の様な判断する必要がある。

if [ $? -eq 1 ]; then
  exit 1
fi

また、for文内だと子プロセス扱いにならない。

#!/bin/bash

animal_list=("cat" "dog" "alligator")

for animal in ${animal_list[@]}
do
    echo $animal

    if [ $animal = "dog" ]; then
        echo "中止!"
        exit 1
    fi
done

echo "だが終わってない"

exit 0

上記コードの実行結果はこちら。

cat
dog
中止!

はまった…。