Quantcast
Viewing all articles
Browse latest Browse all 2722

whileをパイプ入力で回したらexitで終わらなかった話

bashでこんなプログラムを書きました

fruits.txt
apple
banana
orange
#!/bin/bashcat fruits.txt | while read LINE do
    echo${LINE}if[$?-ne 0 ];then
        echo"エラー:${LINE}"exit 1;fi
done

echo"正常終了!"done

解説

fruit.txtの中身をcatしてwhile文にパイプで渡して標準出力するプログラムです。

実行してみる

例えばbananaのechoで失敗した場合、期待される出力は下記となります。

apple
エラー:banana

しかし実際の出力は下記となります。
エラー後にスクリプトが終了せず、後続の処理が続いていますね。

apple
エラー:banana
orange
正常終了!

原因

パイプでwhile文に渡す場合、whileループは元スクリプトの子プロセスとして
実行されてしまいます。
したがって、exit 1をしたとしてもあくまでも子プロセスしか終了せず、
メインの処理は続いてしまいます。

解決策1_子プロセスの戻り値を拾う

子プロセスの戻り値1を親プロセス側で拾って親プロセスを異常終了させます。

cat fruits.txt | while read LINE do
    echo${LINE}if[$?-ne 0 ];then
        echo"エラー:${LINE}"exit 1;fi
done

if[$?-ne 0 ];then
    exit 1;fi

解決策2_for文を使う

for文のリストにcatの結果を指定すれば解決します。
こうすると別途catの結果を入れる変数を定義する必要もないのでスマートかと。

for FRUIT in`cat fruits.txt`;do
    echo${FRUIT}done

Viewing all articles
Browse latest Browse all 2722

Trending Articles