如何在运行的shell脚本被终止时通知另一个shell脚本执行操作
实现方案
以下两种方案都可以满足需求,可根据你的实际场景选择:
方案1:PID轮询监控(无需修改script1,适配性最高)
这种方案不需要调整script1的原有逻辑,哪怕你用pkill -9强制杀死script1也能正常触发逻辑。
- 第一步:启动script1并放到后台后,立刻执行以下命令保存它的PID到临时文件:
echo $! > /tmp/script1.pid$!是shell内置变量,代表最近一个启动的后台进程的PID。 - 第二步:在script2的开头加入监控逻辑,定期检测script1的PID是否存活,检测到进程消失就启动script3:
# 读取script1的PID SCRIPT1_PID=$(cat /tmp/script1.pid) # 检测间隔可自行调整,单位为秒 CHECK_INTERVAL=1 while true; do # kill -0 不会实际发送信号,仅用于检测进程是否存在 if ! kill -0 $SCRIPT1_PID 2>/dev/null; then # 检测到script1不存在,启动script3 /你的/script3/完整路径/script3.sh # 启动后如果不需要继续监控可以直接break退出循环,否则删除break即可 break fi sleep $CHECK_INTERVAL done # 下方继续放script2原本的业务逻辑
方案2:信号通知(实时性更高,无轮询延迟)
如果需要script1被杀死后script2立刻响应,不想有轮询间隔的延迟,可以用信号通知机制,需要少量修改script1和script2的代码。
注意:这种方案对pkill -9(发送SIGKILL信号)的场景不生效,因为SIGKILL信号无法被捕获。
- 第一步:启动script2并放到后台后,立刻执行命令保存它的PID到临时文件:
echo $! > /tmp/script2.pid - 第二步:在script1的开头加入信号捕获逻辑,收到终止信号时先给script2发通知再退出:
# 捕获pkill默认发送的SIGTERM、以及手动Ctrl+C触发的SIGINT等终止信号 trap 'kill -SIGUSR1 $(cat /tmp/script2.pid); exit' SIGTERM SIGINT SIGQUIT # 下方继续放script1原本的业务逻辑 - 第三步:在script2的开头加入信号捕获逻辑,收到script1发来的通知就启动script3:
# 捕获自定义信号SIGUSR1,收到后执行启动script3的逻辑 trap '/你的/script3/完整路径/script3.sh' SIGUSR1 # 下方继续放script2原本的业务逻辑
注意事项
- 临时存放PID的文件用完后可以自行加清理逻辑,避免下次运行时读取到旧PID导致逻辑错误
- 如果你的script1、script2需要多次并行运行,可以给PID文件加唯一后缀区分,比如用当前shell的PID作为后缀:
/tmp/script1.$$.pid
内容的提问来源于stack exchange,提问作者Science Rocker
相关产品推荐
相关产品推荐

