一部のプログラムをテストするbashスクリプトがあり、プログラムの1つがSegmentation fault
を返すため、スクリプトの先頭にトラップを追加しようとしました。
trap "echo 'segfault occured!'" SIGSEGV
しかし、それは何もしませんでした。使った
echo $?
segfaultを生成するプログラムの直後に、出力として139が表示されます。特定のエラーコードのトラップを追加するにはどうすればよいですか?
trap "$instructions" SIGSEGV
は、シェル自体のセグメンテーション違反をトラップします。
set -e
の下でスクリプトを実行する場合、EXIT
(または0
)にトラップを設定できます。これは、スクリプトが終了したときに実行されます(コマンドがゼロ以外のステータスを返したためか、明示的にexit
を呼び出した場合か、スクリプトの最後から落ちた場合)。セグメンテーション違反をテストするには、トラップへの入り口で$?
を確認します。 ($?
は、プログラムがステータス139で正常に戻ったため、139になる可能性があることに注意してください。これは、シェルで処理を行う場合は回避できます。)
set -e
trap 'case $? in
139) echo "segfault occurred";;
esac' EXIT
Bashまたはkshまたはzshでは、ゼロ以外のステータスを返す各コマンドの後にトラップを実行するためにset -e
を使用する必要はありません。代わりにERR
にトラップを置くことができます。以前と同様に、トラップへの入り口で$?
を確認する必要があります。139は、プログラムがこのステータスを返したことを意味する場合があります(ほとんどありません)。
man bash
から:
trap [-lp] [[arg] sigspec ...]
The command arg is to be read and executed when the Shell
receives signal(s) sigspec.
プログラムがsegfaultを実行すると、何らかの方法で子が終了したため、bashはSIGCHLD
を取得します。
ただし、$?
に格納されている終了コードを条件付きで使用して、SIGCHLD
をトラップすることができます。
trap 'if [[ $? -eq 139 ]]; then echo "segfault !"; fi' CHLD
set -bm
が非インタラクティブbash(スクリプトなど)で使用されている場合(おそらくそれが何であるか)が必要になる場合があることに注意してください。
編集:bash
とtrap
。