假设我运行一个脚本
$ nohup ./myscript </dev/null >/dev/null 2>&1 &
然后杀死它
$ pkill myscript
我的脚本应如何设计以便当它接收到信号时SIGKILL
运行另一个命令?
答案1
你不能感染SIGKILL
(并且SIGSTOP
),因此启用自定义处理程序SIGKILL
是没有意义的。
您可以捕捉所有其他信号,因此也许可以尝试围绕这些信号进行设计。
同时做:
pkill myscript
默认情况下pkill
会发送SIGTERM
,而不是SIGKILL
,这显然可以被捕获。
例如,在脚本顶部添加:
trap 'echo foobar' TERM
shelltrap
内置命令用于捕获信号,并分派任何自定义处理程序,或完全忽略信号。
echo foobar
当 shell 收到时,命令就会在这里运行TERM
。
您也可以对其他信号执行相同操作,也可以修改命令以满足您的需要。例如,同时运行两者echo foobar
并执行自定义处理程序脚本:
trap 'echo foobar; /my/custom/handler.sh' TERM
exit
如果您之后有计划:
trap 'echo foobar; /my/custom/handler.sh; exit' TERM
答案2
已接受的答案说,您无法捕获 SIGKILL。顺便说一句,您仍然可以监视脚本的 PID,以查看它是否仍在运行。甚至可以通过在当前脚本的子进程中启动此监视程序来完成此操作:
#!/bin/bash
# Launch a sleeping child process that will be "waited" next
sleep infinity & PID=$!
# Trap "graceful" kills and use them to kill the sleeping child
trap "kill $PID" TERM
# Launch a subprocess not attached to this script that will trigger
# commands after its end
( sh -c "
# Watch main script PID. Sleep duration can be ajusted
# depending on reaction speed you want
while [ -e /proc/$$ ]; do sleep 3; done
# Kill the infinite sleep if it's still running
[ -e /proc/$PID ] && kill $PID
# Commands to launch after any stop
echo "Terminating"
" & )
# Commands to launch before waiting
echo "Starting"
# Waiting for infinite sleep to end...
wait
# Commands to launch after graceful stop
echo "Graceful ending"