信号行为不一致?仅适用于第一个信号?

时间:2015-03-27 18:52:00

标签: bash

在给定特定信号的情况下尝试使用能够使用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}

知道为什么忽略第二个信号? (有些代码,比如在清理中取消注册陷阱可能只是偏执狂)

1 个答案:

答案 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