0

场景如下:我有一个 java 守护进程,它应该不会终止。但是,如果出现意外错误,崩溃的 JVM 应该通过脚本重新启动。所以我写了一个命令来启动一个后台bash,它有一个循环启动JVM(所以当JVM终止时,它将再次重新启动)。

/bin/bash -c "while true; do java ...; done" &

为了能够停止守护进程,我想杀死这个 bash 后台进程(通过将它的进程 ID 保存在文件中)。只要后台 bash 不会重新启动 JVM,但仍然不会杀死当前正在运行的进程,这就是有效的——因此 bash 似乎在检查 kill 命令之前就结束了它的当前命令。我也想杀死当前正在运行的 JVM。

由于我不想管理 2 个 PID(一个用于后台 bash,一个用于当前运行的 JVM),有没有一种“强制终止”的方法,可以通过设计停止当前命令?(我在 man kill 中找不到这样的东西)?

4

3 回答 3

3

有许多进程管理工具正是为此目的而构建的:runit、daemontools、upstart……甚至是 SysV inittab 表中的一个条目。

所有这些都将在关机时立即自动重启,跟踪所需状态而不是当前状态(并尝试根据需要发出启动或关机信号),管理信号传递等。

您可以在 bash 中捕获信号并在其上触发事件,但这仅处理可以捕获的子集(例如,您不能捕获 KILL)。更好的是使用专用的工具。


Wooledge.org wiki的ProcessManagement 页面(由 irc.freenode.org 的#bash 频道使用)有一些其他的关于自己在 bash 中执行此操作的具体建议……尽管它也建议将 runit、daemontools 及其亲属作为最好的 -实践方法。

于 2012-06-18T17:25:48.923 回答
0

为什么不使用cron启动您的应用程序,并且只管理 1 个 pid,即属于您的应用程序的 pid?这样你总是会杀死正确的进程。

强调一下,您可以创建一个 bash 脚本来管理您的应用程序:start|stop|status。启动时,它会将 java pid 保存到文件中。然后您可以安排一个 cron 作业来验证应用程序的状态,如果 pid 不存在,请重新启动它。

于 2012-06-18T17:14:25.087 回答
0

这不是 bash 的默认行为吗?例如,我认为 zsh 会相反并且不会向所有子进程发送 SIGHUP 吗?也许您可以尝试这个答案并编写一个小脚本并以 disown 开头?

看到这个问题:将进程的生命与启动它的外壳联系起来

我没有测试它,但我的网络服务器中需要 zsh,因为我手动启动它并使用双 CTRL-D 退出我的 shell。

于 2012-06-18T19:05:21.857 回答