trap コマンド

trapは外部コマンドではなく、シェルの組み込みコマンドで、シェルスクリプトがシグナルを受信したときの動作を設定するもの。シグナルの種類には番号がついていて、番号ごとに受信したときに実行するスクリプトを設定できる。

# SIGINTを受信したときに interrupted と表示して終了する
trap "echo interrupted; exit 1" 2
# または
trap "echo interrupted; exit 1" INT

シグナルの番号ごとに微妙に癖があるものがある。また本物のシグナルの他に擬似シグナルというのもある。

bashでは、help trap というふうに help コマンドでシェルの組み込みコマンドのヘルプを表示できる。help も組み込みコマンドである。残念ながらzshではできないみたい。

シグナル番号 0 または EXIT

擬似シグナル EXIT はスクリプトが終了するタイミングをトラップする。0と書いてもよい。

trap で指定するコードの中に exit で終了コードを指定すれば、スクリプト全体のもともとの終了コードが上書きされて、それに変わる。

trap "echo trap0" EXIT
# または
trap "echo trap0" 0

# => 終了コード: 0

trap "echo trap0" 0
exit 1

# => 終了コード: 1

trap "echo trap0; exit 2" 0

# => 終了コード: 2

trap "echo trap0; exit 2" 0
exit 1

# => 終了コード: 2

擬似シグナル ERR

実行したコマンドの終了コードが0以外だったときをトラップできる。途中で実行したすべてのコマンドで0以外だったものをすべてトラップされる。擬似シグナル ERRbash 独自の機能みたい。

コマンドすべてというわけではなく、ifの条件式にあるコマンドは、0以外を返してもトラップしない。

#!/bin/bash
trap "echo err" ERR
test 1 = 2
if test 1 = 2; then
    echo "message 1"
fi
echo "message 2"
# 出力
# err
# message 2

trap で指定するコードの中に exit を入れれば、そこでスクリプトが終了する。

#!/bin/bash
trap "echo err; exit 1" ERR
test 1 = 2
echo "message"
# 出力
# err
このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。