#!/bin/bash
SELF_PID=$$
sig_HUP_handler() {
echo caught SIGHUP
kill -TERM $SELF_PID
}
trap "echo caught SIGTERM ; exit 1" SIGTERM
trap "sig_HUP_handler ; exit 2" SIGHUP
kill -HUP $SELF_PID
exit 0
このスクリプトを実行して確認してみたら、終了コードが 2 でした。つまり、SIGTERM に対する trap は実行されませんでした。
[root@hoge ~]# ./trap_test.bash
caught SIGHUP
[root@hoge ~]# echo $?
2
[root@hoge ~]# strace ./trap_test.bash
...
kill(9607, SIGHUP) = 0
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=9607, si_uid=0} ---
rt_sigreturn({mask=[]}) = 0
rt_sigprocmask(SIG_BLOCK, [HUP], [], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP], 8) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0264e7a000
write(1, "caught SIGHUP\n", 14caught SIGHUP
) = 14
kill(9607, SIGTERM) = 0
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=9607, si_uid=0} ---
rt_sigreturn({mask=[HUP]}) = 0
rt_sigprocmask(SIG_SETMASK, [HUP], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
exit_group(2) = ?
+++ exited with 2 +++
[root@hoge ~]#
strace をかけてみると、このように SIGTERM は確かに割り込んでいます。次に、exit 2 を行わないようにして、実験してみました。
[root@hoge ~]# diff trap_test.bash trap_test2.bash 11c11 < trap "sig_HUP_handler ; exit 2" SIGHUP --- > trap "sig_HUP_handler # exit 2" SIGHUP [root@hoge ~]# ./trap_test2.bash caught SIGHUP caught SIGTERM [root@hoge ~]# echo $? 1終了コードは 1 になりました。つまり、SIGHUP に対する trap 完了後に、SIGTERM に対する trap が実行されました。
なお、上記の実験環境は、CentOS7 bash-4.2.46-31.el7.x86_64 です。同じスクリプトを RHEL4 より古い環境で動かすと bash が segfault してしまいます。当時は、想定されていなかったのでしょうね。 シグナルには気をつけよう!

0 件のコメント:
コメントを投稿