用Java创建Nohup进程

问题描述 投票:0回答:1

使用ProcessBuilder,我一直在尝试创建一个独立的进程,当JVM终止时不会终止,但似乎没有任何工作。

我已经尝试过/usr/bin/nohup commands,但是当启动它的JVM终止时,它似乎仍然会终止。有没有办法在Java中实现这一目标?

java linux jvm processbuilder nohup
1个回答
2
投票

首先,我们首先要编写一个测试脚本来验证您所看到的内容:

$ cat /tmp/test.sh 
#!/bin/bash

for sig in SIGINT SIGTERM SIGHUP; do
  trap "echo Caught $sig" $sig
done

echo Traps registered, sleeping
sleep 10
echo Done sleeping, exiting

当我通过以下方式调用时:

new ProcessBuilder("/tmp/test.sh").inheritIO().start().waitFor(1, TimeUnit.SECONDS);

我看到Java进程在1秒后终止(自waitFor()超时),但子进程继续运行(在JVM退出后,Done sleeping消息被打印到控制台)。这与this question中讨论的内容排列在一起。

所以我建议做的第一件事是验证你最初假设子进程实际上被杀死了;或许还有别的东西会因为另一个原因导致它死亡。使用.inheritIO()可以帮助调试,以防子进程生成您没有看到的错误消息。


所有这一切,nohup可能不是你想要的,就像'那个其他人'的笔记; nohup只会导致一个进程忽略SIGHUP,它仍然会尊重其他信号,例如SIGINTSIGTERM(例如Process.destroy() sends a SIGTERM)。有关更多信息,请参阅this question

与编程中的所有问题一样,引入更多层可能会有所帮助:)

创建一个处理所需的disowning逻辑的shell脚本,例如:

$ cat start-and-disconnect.sh
#!/bin/bash

# obviously tweak this as necessary to get the behavior you want,
# such as redirecting output or using disown instead of nohup
nohup "$@" & 

这里的优点是Bash(或您喜欢的任何shell)具有比Java更好的进程管理控制,现在您可以单独测试它,而无需编译和运行Java应用程序。

一旦您对脚本感到满意,您的Java代码就会变成:

new ProcessBuilder("/path/to/start-and-disconnect.sh", "/path/to/your_binary.sh")
    .inheritIO().start().waitFor();

您可以安全地.waitFor()完成调用,因为start-and-disconnect.sh将在启动其子进程后退出。

© www.soinside.com 2019 - 2024. All rights reserved.