2014年8月14日木曜日

シェルスクリプトのif文

あるコマンドの戻り値で条件分岐したい時に以下の様に書いているシェルスクリプトを結構な頻度で見掛けます。例えばgrepして特定の行が見付かった時なんかです。

grep -i "error" $LOGFILE >/dev/null 2>&1
ret=$?
if [ $ret -eq 0 ]
then
  ;; grepで目的の行が見付かった時の処理
fi

Bシェル系で直前に実行したコマンドの戻り値が$?に入る事を利用している訳ですが、この書き方は無駄ですしバグが混入し易いですよね。ifの条件も分かり難い。例えば後日別の人がこのシェルスクリプトを修正する時に、以下の様に変更したら期待した動作をしなくなります。

grep -i "error" $LOGFILE >/dev/null 2>&1
echo $LOGFILE ;; for print debug
RET=$?
if [ $RET -eq 0 ]
then
  ;; grepで目的の行が見付かった時の処理
fi

意外と知らない人が多いみたいなのですが、if文の後の開き大括弧"["testコマンドの糖衣構文です。which -a "["とすると/usr/binあたりに"["コマンドがある筈です。

if自体は直後のコマンドの戻り値が0かそれ以外かを判定して、then節かelse節を実行する文というだけなので、ifの直後に必ず大括弧[]がくる必要はありません。ただifの判定文にtestコマンドを使う事が頻繁にあるので糖衣構文として[]が用意されていて、それを判定文に使うシェルスクリプトの記法が一般化し過ぎているだけです。なので前記のコードは以下の様に書く事が出来ます。

if grep -i "error" $LOGFILE >/dev/null 2>&1
then
  ;; grepで目的の行が見付かった時の処理
fi

これだとifの条件が一目で分かるしバグの混入も減るでしょう。

0 件のコメント:

コメントを投稿