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

Bash 不一致的信号行为?仅适用于第一个信号?,bash,Bash,试图让脚本能够在给定特定信号的情况下使用exec(以便它可以选择任何“升级”)重新启动自身(已尝试SIGHUP&SIGUSR1) 这似乎第一次有效,但第二次无效,即使注册(trap)确实在execed实例(仍然是相同的PID)中重复出现 我是这样运行它的: ./tst.sh & TSTPID=$! # Starts ok, see both "hi" & "ho" messages sleep 10 kill -USR1 ${TSTPID} # Restarts ok, see

试图让脚本能够在给定特定信号的情况下使用
exec
(以便它可以选择任何“升级”)重新启动自身(已尝试
SIGHUP
&
SIGUSR1

这似乎第一次有效,但第二次无效,即使注册(
trap
)确实在
exec
ed实例(仍然是相同的PID)中重复出现

我是这样运行它的:

./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}

知道为什么忽略第二个信号吗?(一些代码,比如在清理中取消注册陷阱可能只是一种妄想)

可能是因为您正在从信号处理程序执行,信号代码由于exec而继续运行并被遗忘,或者阻止其他清理代码或菊花链处理程序执行

谁知道操作系统信号处理代码的黑盒中发生了什么,以及bash自己在上面的分层,exec可能会绕过它们。exec是一项非常严厉的措施:-)

也看看这个。我正在寻找处理信号的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

cleanup()中陷阱声明中的“-”是否将信号重置为默认值(未陷阱)?比如BASH帮助陷阱,是的,但我认为它是偏执狂。exec实际上应该重置trap(在C中是AFAIK),并在没有参数的情况下运行
trap
,显示当前的trap表。当我运行上面的代码时,它为第一次和第二次执行显示了相同的表现在您处于1024轮,与您的ID很匹配
#!/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