share facebook facebook twitter menu hatena pocket slack

2012.10.25 THU

シェルスクリプトで例外処理(try-catch文)のような動作を行う

鈴木 宏康

WRITTEN BY 鈴木 宏康

シェルスクリプトで例外処理(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文で$?をチェックしていました。

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら

鈴木 宏康

鈴木 宏康

愛知県生まれ。東京工業大学大学院修士課程修了。在学時より、ベンチャー企業でインターネットに関する業務に携わり、現在はクラウド(主にAmazon Web Services)上での開発・運用を軸とした事業の、業務の中心として活躍。

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。