bash trap '' 与 trap 函数传递信号
bash trap '' vs trap function passing signals
我对使用陷阱将信号转发给子进程感到困惑。假设我有两个脚本:
a.sh
#!/bin/bash
# print the process id
echo $$
cleanup() {
rv=$?
echo "cleaning up $rv"
exit
}
sleep 5
trap '' SIGTERM # trap cleanup SIGTERM
echo 'cant stop wont stop'
./b.sh
echo 'can stop will stop'
trap - SIGTERM
sleep 4
echo 'done'
b.sh
#!/bin/bash
sleep 4;
echo 'b done'
如果我执行 a.sh
然后从另一个 window 使用 kill -- -PGID
终止进程组,SIGTERM 将被忽略并且不会传递给 b.sh
。但是,如果我执行 trap cleanup SIGTERM
,SIGTERM 通过并终止 b.sh
。为什么我的陷阱在一种情况下通过信号而不是另一种情况?
trap [action condition ...]
If action is null ( "" ), the shell shall ignore each specified condition if it arises.
所以当你执行TRAP '' SIGTERM
时,SIGTERM
条件被忽略。尝试使用 space 值,看看它是否有效:
sleep 5
trap ' ' SIGTERM # Note the space (' ')!!
echo 'cant stop wont stop'
./b.sh
echo 'can stop will stop'
trap - SIGTERM
sleep 4
echo 'done'
这很有趣。引用 man 7 signal
:
A child created via fork(2) inherits a copy of its parent's signal dispositions. During an execve(2), the dispositions of handled signals are reset to the default; the dispositions of ignored signals are left unchanged.
在您的情况下,child 总是会收到 TERM
,因为它们位于同一个进程组中。问题是,它有什么用。
当 parent 忽略 TERM
时,根据上面的规则,child 也会忽略 child幸存下来。当parent 捕获 TERM
时,child的handler会被重置,默认会死
我对使用陷阱将信号转发给子进程感到困惑。假设我有两个脚本:
a.sh
#!/bin/bash
# print the process id
echo $$
cleanup() {
rv=$?
echo "cleaning up $rv"
exit
}
sleep 5
trap '' SIGTERM # trap cleanup SIGTERM
echo 'cant stop wont stop'
./b.sh
echo 'can stop will stop'
trap - SIGTERM
sleep 4
echo 'done'
b.sh
#!/bin/bash
sleep 4;
echo 'b done'
如果我执行 a.sh
然后从另一个 window 使用 kill -- -PGID
终止进程组,SIGTERM 将被忽略并且不会传递给 b.sh
。但是,如果我执行 trap cleanup SIGTERM
,SIGTERM 通过并终止 b.sh
。为什么我的陷阱在一种情况下通过信号而不是另一种情况?
trap [action condition ...]
If action is null ( "" ), the shell shall ignore each specified condition if it arises.
所以当你执行TRAP '' SIGTERM
时,SIGTERM
条件被忽略。尝试使用 space 值,看看它是否有效:
sleep 5
trap ' ' SIGTERM # Note the space (' ')!!
echo 'cant stop wont stop'
./b.sh
echo 'can stop will stop'
trap - SIGTERM
sleep 4
echo 'done'
这很有趣。引用 man 7 signal
:
A child created via fork(2) inherits a copy of its parent's signal dispositions. During an execve(2), the dispositions of handled signals are reset to the default; the dispositions of ignored signals are left unchanged.
在您的情况下,child 总是会收到 TERM
,因为它们位于同一个进程组中。问题是,它有什么用。
当 parent 忽略 TERM
时,根据上面的规则,child 也会忽略 child幸存下来。当parent 捕获 TERM
时,child的handler会被重置,默认会死