1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

fruits.txt
apple
banana
orange
# !/bin/bash

cat 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
1
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?