在给定特定信号的情况下尝试使用能够使用exec
重新启动自身的脚本(以便它可以选择“升级”)(已尝试SIGHUP
& SIGUSR1
)
这似乎是第一次,但不是第二次,即使注册(trap
)确实在exec
ed实例(仍然是相同的PID)中重现。
#!/usr/bin/env bash
set -x
readonly PROGNAME="${0}"
function run_prog()
{
echo hi
sleep 2
echo ho
sleep 1000 &
wait $!
}
restart()
{
sleep 5
exec "${PROGNAME}"
}
trap restart USR1
echo -e "TRAPS:"
trap
echo
run_prog
这是我运行它的方式:
./tst.sh & TSTPID=$! # Starts ok, see both "hi" & "ho" messages
sleep 10
kill -USR1 ${TSTPID} # Restarts ok, see both "hi" & "ho" messages
sleep 10
kill -USR1 ${TSTPID} # NOTHING HAPPENS
sleep 5
kill ${TSTPID}
知道为什么忽略第二个信号? (有些代码,比如在清理中取消注册陷阱可能只是偏执狂)
答案 0 :(得分:1)
也许是因为你从信号处理程序执行,信号代码继续运行并由于exec而继续被遗忘,或阻止其他清理代码或菊花链处理程序执行。
谁知道操作系统信号处理代码的黑盒中发生了什么,并且bash自己的分层可能会被exec规避。 exec是一个非常严厉的措施:-)
另请查看此cool bash site。我正在寻找处理信号的bash源代码。好奇。
这里的解决方案是正确的方法:
#!/usr/bin/env bash
set -x
readonly PROGNAME="${0}"
DO_RESTART=
function run_prog()
{
echo hi
sleep 2
echo ho
sleep 1000 &
SLEEPPID=$!
#builtin
wait ${SLEEPPID}
}
trap DO_RESTART=1 SIGUSR1
echo -e "TRAPS:"
trap -p
echo
run_prog
if [ -n "${DO_RESTART}" ]; then
sleep 5
kill ${SLEEPPID}
exec "${PROGNAME}"
fi