java - 在 Java 中创建一个 Nohup 进程

标签 java linux jvm processbuilder nohup

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

我已经尝试过 /usr/bin/nohup 命令,但是当启动它的 JVM 终止时,它似乎仍然终止。有什么方法可以在 Java 中实现这一点?

最佳答案

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

$ 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() 超时),但是子进程继续运行(Done sleeping 消息在 JVM 退出后打印到控制台)。这与 this question 中讨论的内容一致.

所以我建议做的第一件事是验证您最初的假设,即子进程实际上正在被杀死;也许其他原因导致它因其他原因而死亡。使用 .inheritIO() 可以帮助调试,以防子进程生成您没有看到的错误消息。


综上所述,nohup 可能不是您想要的,正如“那个人”所指出的那样; nohup 只会导致进程忽略 SIGHUP,它仍然会尊重其他信号,特别是 SIGINTSIGTERM ( Process.destroy() sends a SIGTERM ,例如)。参见 this question了解更多。

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

创建一个 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 将在启动其子进程后退出。

关于java - 在 Java 中创建一个 Nohup 进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52394419/

相关文章:

java - 获取 JavaFX 场景图上的所有阶段

android - Flutter 运行(同步文件)未完成

java - Hudson 无法使用 unix 用户/组进行身份验证

java - 如何找到继承给定接口(interface)的类实例?

Java 对 Runtime.memory() 与 Windows 的物理内存使用历史图的混淆

java - 对象不断提升到 Old Gen

java - 如何在swing中将元素添加到JList?

java - jdbcAuthentication() 而不是 inMemoryAuthentication() 不提供访问权限 - Spring Security 和 Spring Data JPA

c++ - Arduino 的替代 IDE

java - 无法将目录从 Eclipse(Helios) 复制并粘贴到 Windows