我有一个启动守护进程然后休眠 20 秒的脚本。如果我在 SLES11 SP1 或 RHEL6 上运行脚本,那么在脚本退出后进程仍在运行。
如果我在 SLES11 SP3 或 RHEL6.3 上运行脚本,那么在脚本退出后进程将不再运行。该进程将继续运行整个 20 秒的睡眠时间,并在进程退出时被终止。
该脚本通过 expect 运行,因此脚本的整个 shell 随进程退出。显然,如果这不是一个守护进程,它正在启动,我不会感到惊讶。另外,我怀疑问题不在于操作系统版本,而在于我们设置新服务器的方式不同(虽然不知道这些差异是什么,但旧服务器是几年前设置的)。
在 20 秒内,如果我执行 ps,进程运行,我得到以下信息:
root 4699 1 0 15:14 pts/2 00:00:00 sudo -u openmq /opt/PacketPortal/openmq/default/bin/imqbrokerd -bgnd -autorestart -silent -port 7676 -Dimq.service.activelist=admin,ssljms -D
openmq 4701 4699 0 15:14 pts/2 00:00:00 /bin/sh /opt/PacketPortal/openmq/default/bin/imqbrokerd -bgnd -autorestart -silent -port 7676 -Dimq.service.activelist=admin,ssljms -Dimq.ssl
openmq 9095 9063 54 16:21 pts/2 00:00:02 /usr/java/latest/bin/java -cp /opt/PacketPortal/openmq/default/bin/../lib/imqbroker.jar:/opt/PacketPortal/openmq/default/bin/../lib/imqutil.jar:/opt/PacketPortal/ope
4699 的父进程为 1 这一事实似乎向我表明该进程已被正确守护进程。然而,在 expect 脚本退出后,4699 和 4701 都被杀死了。是什么原因造成的?
更新
我在工作的服务器上打印了相同的输出。在 20 秒的睡眠中,我得到:
openmq 18652 1 0 15:44 pts/1 00:00:00 /bin/sh /opt/PacketPortal/openmq/default/bin/imqbrokerd -bgnd -autorestart -silent -port 7676 -Dimq.service.activelist=admin,ssljms -Dimq.ssljms.tls.port=7680
openmq 18686 18652 8 15:44 pts/1 00:00:02 /usr/java/latest/bin/java -cp /opt/PacketPortal/openmq/default/bin/../lib/imqbroker.jar:/opt/PacketPortal/openmq/default/bin/../lib/imqutil.jar:/opt/PacketPortal/ope
20 秒睡眠后,我得到:
openmq 18652 1 0 15:44 ? 00:00:00 /bin/sh /opt/PacketPortal/openmq/default/bin/imqbrokerd -bgnd -autorestart -silent -port 7676 -Dimq.service.activelist=admin,ssljms -Dimq.ssljms.tls.port=7680
openmq 18686 18652 5 15:44 ? 00:00:02 /usr/java/latest/bin/java -cp /opt/PacketPortal/openmq/default/bin/../lib/imqbroker.jar:/opt/PacketPortal/openmq/default/bin/../lib/imqutil.jar:/opt/PacketPortal/ope
脚本退出后,它会断开控制终端。我想知道为什么它不在较新的服务器上执行此操作。
更新
这是实际启动 OpenMQ 的脚本部分。-bgnd 标志应该用来守护它。
sudo -u openmq $IMQ_HOME/bin/$EXECUTABLE -bgnd $BROKER_OPTIONS $ARGS > /dev/null 2>&1 &
更新
我偶然发现了一些真正奇怪的行为。如果我将命令更改为:
sudo -u openmq sldkhglksj; $IMQ_HOME/bin/$EXECUTABLE -bgnd $BROKER_OPTIONS $ARGS > /dev/null 2>&1 &
然后我sldkhglksj: command not found
当然得到了但是...... openmq进程没有被杀死。如果我取出那个零钱,它就会被杀死。
更新
回想起来,神奇的命令似乎将 sudo 更改为不在实际的 openmq 启动时运行,这让我相信 sudo 以某种方式参与其中。
您可能遇到了此处记录的这个问题:https ://access.redhat.com/knowledge/solutions/180243 。
它指出,与您所描述的类似的操作的 sudo 行为在 RHEL/CentOS 6.3 (sudo-1.7.4p5-11.el6.x86_64) 附带的版本中发生了变化。您看到 RHEL 6 和 6.3 之间的不同行为并且这涉及 sudo 的事实是我指出这一点的原因。
尝试一些选项(我没有 100% 的答案,只是抛出一些想法):
sudo
,例如su -c '/opt/PacketPortal/openmq/default/bin/imqbrokerd -bgnd -autorestart -silent -port 7676 -Dimq.service.activelist=admin,ssljms -D' - openmq
- 请参阅http://www.linfo.org/su.html了解更多信息sudo
本来解决这个问题(hacky,我知道,但你可以在一个临时位置构建/安装它来测试它)huponexit
shopt
Massimo 引用的答案,如果这不是我上面提到的 sudo 问题,那听起来很有希望您可以在脚本中为您希望守护进程的命令添加前缀:
然后当外部脚本完成时,程序将继续运行。
在后台处理后,尝试
disown
在其自己的一行中添加一个。这应该可以防止您的 shell 在退出时向任何子进程发送信号。也尝试添加
</dev/null
到启动命令。不确定该
-bgnd
标志应该如何作为您的进程的背景,但是如果它们的标准输入丢失,进程可能会死亡,这正是您失去 ssh 连接时发生的情况。您已经将所有输出丢弃到 bitbucket,您可能想确保也没有输入。我无法解释行为的变化,但我的建议是接受它。