场景如下:我有一个java守护进程,它应该不会终止。但是,如果出现意外错误,应该通过脚本重新启动崩溃的JVM。所以我写了一个命令,它启动一个后台bash,它有一个循环启动JVM(所以当JVM终止时,它会再次重启)。
/bin/bash -c "while true; do java ...; done" &
为了能够停止守护进程,我想到了杀死这个bash后台进程(通过在文件中保存它的进程ID)。这可以工作,因为后台bash不会重新启动JVM,但仍然不会终止当前正在运行的进程 - 因此bash似乎在检查kill命令之前结束它的当前命令。我想让当前正在运行的JVM被杀死。
由于我不想管理2个PID(一个用于后台bash,一个用于当前运行的JVM),有没有一种“强制终止”的方法,它设计会停止当前命令? (我在男人身上找不到这样的东西)?
答案 0 :(得分:3)
为此目的构建了许多流程管理工具:runit,daemontools,upstart ......甚至是SysV inittab表中的条目。
所有这些都将在关机时立即自动重启,跟踪所需状态而不是当前状态(并尝试根据需要发出启动或关机信号),管理信号传递等。
您可以在bash中捕获信号并在其上触发事件,但这只能处理可以被捕获的子集(例如,您无法捕获KILL)。更好的方法是使用内置的工具。
ProcessManagement page of the wooledge.org wiki(由irc.freenode.org' #bash频道使用)有一些其他具体的建议,你自己在bash中做这个...虽然它也暗示了runit,daemontools和他们的亲属作为最佳实践方法。
答案 1 :(得分:0)
为什么不使用cron启动您的应用,只管理1个pid,属于您的应用的pid?这样你就会永远杀死正确的过程。
强调一下,你可以创建一个bash脚本来管理你的app:start | stop | status。启动时,它会将java pid保存到文件中。然后,您可以安排一个cron作业来验证应用程序的状态,如果pid不存在,请重新启动它。
答案 2 :(得分:0)
这不是bash的默认行为吗?我认为例如zsh做了相反的事情,并没有向所有子进程发送SIGHUP?也许你可以尝试这个答案,然后编写一个小脚本并以不公开的方式启动它?
请参阅此问题:Tie the life of a process to the shell that started it
我没有测试它,但我需要在我的网络服务器中使用zsh,因为我手动启动它并使用双CTRL-D退出我的shell。