在用xshell 时 重启tomcat 后 不ctrl + c ,直接点击右上角‘X’ , 这是tomcat 会 退出进程。
restart_tomcat.sh 脚本:
ps -ef|grep '^.*java.*'"apache-tomcat-$1"'.*$'|grep -v grep|awk '{print $2}'|xargs kill -9
/opt/apache-tomcat-$1/bin/startup.sh
tail -f /opt/apache-tomcat-$1/logs/catalina.out
改过之后:
ps -ef|grep '^.*java.*'"apache-tomcat-$1"'.*$'|grep -v grep|awk '{print $2}'|xargs kill -9
set -m
/opt/apache-tomcat-$1/bin/startup.sh
tail -f /opt/apache-tomcat-$1/logs/catalina.out
注: 增加作业控制。
详解:http://hongjiang.info/why-kill-2-cannot-stop-tomcat/
交互模式与非交互模式对作业控制(job control)默认方式不同
为什么在交互模式下shell不会对后台进程处理SIGINT
信号设置为忽略,而非交互模式下会设置为忽略呢?还是比较好理解的,举例来说,我们先某个前台进程运行时间太长,可以ctrl-z
中止一下,然后通过bg %n
把这个进程放入后台,同样也可以把一个cmd &
方式启动的后台进程,通过fg %n
放回前台,然后在ctrl-c
停止它,当然不能忽略SIGINT
。
为何交互模式下的后台进程会设置一个自己的进程组ID呢?因为默认如果采用父进程的进程组ID,父进程会把收到的键盘事件比如ctrl-c
之类的SIGINT
传播给进程组中的每个成员,假设后台进程也是父进程组的成员,因为作业控制的需要不能忽略SIGINT
,你在终端随意ctrl-c
就可能导致所有的后台进程退出,显然这样是不合理的;所以为了避免这种干扰后台进程设置为自己的pgid。
而非交互模式下,通常是不需要作业控制的,所以作业控制在非交互模式下默认也是关闭的(当然也可以在脚本里通过选项set -m
打开作业控制选项)。不开启作业控制的话,脚本里的后台进程可以通过设置忽略SIGINT
信号来避免父进程对组中成员的传播,因为对它来说这个信号已经没有意义。
回到tomcat的例子,catalina.sh脚本通过start参数启动的时候,就是以非交互方式后台启动,java进程也被shell设置了忽略SIGINT
信号,因此在ctrl-c
结束test.sh进程时,系统发送的SIGINT
对java没有影响。