Shell脚本里后台进程忽略SIGINT、SIGQUIT信号

写问题之前,大家不妨跟我做个小实验,直接运行一个脚本:

temp.sh

内容只有一行:sleep 1000 &

运行temp.sh,sleep进程在后台运行,使用ps -ef | grep sleep得到sleep的PID,使用 kill -SIGINT PID,无效,kill -SIGQUIT PID,无效,kill -SIGHUP PID,成功


正文

今天上线发生了一个故障,大概为:从脚本中启动tomcat,然后退出终端,tomcat退出,然而我们并不知道,当发现的时候,发现线上的tomcat进程都没了。

原因是因为,使用脚本启动,脚本中关键的有两句:

start_tomcat.sh #启动tomat

tail -f search.log #查看日志

而那个start_tomcat.sh,创建了tomcat的后台进程,在执行tail -f search.log 的时候,整个脚本还没有退出,这时关闭了终端,终端会发送 SIGHUP 信号到脚本,后台进程也收到了信号,Java程序没有对 SIGHUP 信号作特殊处理,所以Linux默认终止程序。

后来我们发现,如果在运行脚本的时候,按Ctrl + C ,也就是发送 SIGINT 信号到脚本,tomcat后台进程依旧收到了 SIGINT(可以使用 strace -e trace=singal -p 进程ID监视进程的信号处理),但是tomcat却没有退出,查询资料后发现是因为:

Linux对于脚本中启动的后台进程,将进程的 SIGINT 信号的处理函数改为了 SIGIGN ,即忽略,其实,除了SIGINT,SIGQUIT 的处理也是一样的。

在整个脚本没有退出的情况下,按Ctrl + C,进程收到 SIGINT 信号,但是处理函数是忽略,所以tomcat没有退出,而退出终端,发送的信号是 SIGHUP,tomcat收到后,自己停止。

参考:

shell脚本里后台进程忽略SIGINT信号问题排查

tomcat进程意外退出的问题分析

你可能感兴趣的:(Shell脚本里后台进程忽略SIGINT、SIGQUIT信号)