Bashの擬似シグナルを使ったデバッグ方法
少し前にオライリーの入門Bashを読んで、このデバッグ方法を知って「おおー」と感動をしたので、この喜びを書いてみました。
sh系には trap というコマンドでシグナルトラップができて便利ですが、bash にはさらに便利な疑似シグナルというものがあったりします。bashのmanpagerをみると、trapのsigspecをERRとした場合、コマンドが0以外でexitした場合にトラップしてくれるようです。
If a sigspec is ERR, the command arg is executed whenever a simple command has a non-zero exit status, subject to the following conditions.
The ERR trap is not executed if the failed command is part of the command list immediately following a while or until keyword, part of the test
in an if statement, part of a command executed in a && or ?? list, or if the command's return value is being inverted via !.
These are the same conditions obeyed by the errexit option.
以下は疑似シグナルERRを使ったサンプルコードです。
#!/bin/bash errtrap() { errcode=$? echo "error line $1: command exited with status $errcode." } trap 'errtrap $LINENO' ERR failure() { return 1; } success() { echo "success: bash function .."; return 0; } while true; do sleep 1 if [ $(($RANDOM%2)) -eq 1 ]; then failure else success fi sl > /dev/null 2>&1 #external command done
実行して、見事にシェル関数のエラーと外部コマンドのエラーのときにトラップできています。$LINENOという変数でエラー時の行番号をだしているところもいい感じです。
$ bash test.sh success: bash function .. error line 21: command exited with status 127. success: bash function .. error line 21: command exited with status 127. error line 11: command exited with status 1. error line 21: command exited with status 127. success: bash function .. error line 21: command exited with status 127. error line 11: command exited with status 1. error line 21: command exited with status 127. ^C
疑似シグナルはERRだけでなく色々あったりします。
疑似シグナル | タイミング |
---|---|
EXIT | シェルがスクリプトを終了した |
ERR | コマンド、シェル関数から0ではない終了ステータスが返された |
DEBUG | シェルが文を実行した |
RETURN | source または . で実行されたシェル関数/スクリプトが終了した |
便利で結構気に入っているTIPSでした。*1
- 作者: Cameron Newham,Bill Rosenblatt,株式会社クイープ
- 出版社/メーカー: オライリージャパン
- 発売日: 2005/10/27
- メディア: 大型本
- 購入: 5人 クリック: 109回
- この商品を含むブログ (42件) を見る
*1:でも仕事ではBourne Shellで書くから使う機会が少ないのが悲しい