2012年9月14日金曜日

シェルスクリプトで例外処理(try-catch文)的なもの


スズキです。

"set -e"と"trap"を使うことで可能です。

まず正常終了(exit 0)する下記のスクリプト(sub.sh)を用意します。
#!/bin/sh

echo sub
exit 0

そして"sub.sh"を呼び出す"main.sh"を用意します。
#!/bin/sh

./sub.sh

echo OK
exit 0

実行すると、当然、下記のように出力されます。
# ./main.sh 
sub
OK

次に"sub.sh"を異常終了(exit 1)するようにします。
#!/bin/sh

echo sub
exit 1

それでも"main.sh"は最後(echo OK)まで処理されます。
 ./main.sh 
sub
OK

異常終了した時点で処理を終了するには"set -e"を使います。
"set -e"はコマンドの終了ステータスが0以外のときに、そこで処理が止まるようにします。
#!/bin/sh

set -e

./sub.sh

echo OK
exit 0

実際に実行してみると"main.sh"は最後まで処理されず、
"sub.sh"のところで処理が止まっていることがわかります。
# ./main.sh 
sub

しかし、異常終了の場合はエラーメッセージを出力したりなど、
何らかの処理をしたいことは多々あり、それは下記のように
"trap"を使うことで実現できます。
#!/bin/sh

set -e
trap 'echo NG' ERR

./sub.sh

echo OK
exit 0
"trap"は第一引数が異常終了時に実行する処理で、
第二引数(それ以降)が対象の終了ステータスです
(ですので終了ステータス"0"の正常終了でも"trap"を使うことはできます)
そして第二引数に指定されている"ERR"は"0"以外の終了ステータスを表します。

実際に実行すると、"trap"で仕掛けた処理が実行されていることがわかります。
# ./main.sh 
sub
NG

最後に"sub.sh"を正常終了(exit 0)に戻して、正常終了時の振る舞いを確認します。
#!/bin/sh

echo sub
exit 0

実行する"trap"の処理は行われず、最初に示したものと同様に、
最後(echo OK)まで処理されていることが確認できます。
# ./main.sh 
sub
OK

いつもif文で"$?"チェックしてた...
--------
http://www.suz-lab.com

0 コメント: