シェルスクリプトのエラー時の処理としては、
- シェルスクリプト内部でエラーハンドリングする
- 「set -e」で、エラー発生時にスクリプト自体を止める
とか、いくつか方法があると思います。
今回、「2. の方法で、後からエラーコードって取れるのか?」が気になったので、ちょっと試してみました。
今回の記事の実行環境
- CentOS 7.5
用意したスクリプト
test.sh
#!/bin/bash
ls NULL # NULL は存在しないディレクトリ
ret=$?
[ "$ret" -eq "0" ] || echo "errorcode: $ret"
実行
まずは、普通に実行。
$ ./test.sh
ls: NULL にアクセスできません: そのようなファイルやディレクトリはありません
errorcode: 2
$ echo $?
0
エラー処理である echo が正常に完了しているので、echo $?
は 0
ですね。エラーコードはスクリプト内で出力しているので、そちらの出力を見れば分かります。
次に、-e
オプションを付与して実行してみます。
$ sh -e ./test.sh
ls: NULL にアクセスできません: そのようなファイルやディレクトリはありません
と、スクリプト内のエラー出力コードまで行かず、スクリプトは停止します。直後に echo $?
を実行すると
$ echo $?
2
と。きちんと取れました。しかし、お分かりの通り、直後に同一のシェルで echo $?
を実行しないと、エラーコードは取れません。
おわりに
ということで、シェルスクリプトの実行時に「set -e」でエラー時に処理を止めた場合でも、そのあとで echo $?
を実行すればエラー番号はちゃんと確認できることが分かりました。
この -e
オプション、「ファイルの作成やデータ更新、削除」などの後続処理に入らずに止めてくれるので便利といえば便利ですが、「エラー時に一時ファイルを削除する」といった処理もできなくなってしまうので、「正常系だけ実行できればよく後処理なども無い (アトミックな処理) もしくは、割り切って後処理は手動でやる」ってくらいのスクリプトなら、いい感じにマッチしそうです。「特定の後続処理は残したい」場合には、スクリプト内でひと工夫が必要になります。1