[注意。这与 How do I launch a completely independent process from a Java program? 有关但不同]
我希望能够从“管理器”Java 进程中生成外部进程(shell 脚本),当 JVM 被杀死时,该进程应该继续运行 - 但似乎当我杀死父 Java 程序时, child 也被杀死了(请注意,如果 JVM 自然退出,行为会有所不同)。我有的最简单的测试程序是:
public class Runit {
public static void main(String args[]) throws IOException, InterruptedException {
Runtime.getRuntime().exec(args[0]);
// doesn't work this way either
// ProcessBuilder pb = new ProcessBuilder(args[0]);
// pb.start();
while (true) {
System.out.println("Kill me");
Thread.sleep(2000);
}
}
}
和外部脚本:
#!/bin/sh
while [ 1 ] ; do
ls
sleep 1
done
运行方式
java -classpath jar-with-dependencies.jar temp.exec.Runit runit.sh
如果管理器简单地退出(即取出 Java 程序中的“while”循环),那么生成的进程会继续运行,但是当我 Ctrl+c Java 程序外部程序也被杀死,这不是我想要的。
我在 Ubuntu 上使用 OpenJDK 1.6。
Edit1:将 exec 更改为
Runtime.getRuntime().exec("/usr/bin/nohup " + args[0]);
没有帮助。
Edit2:添加关闭 Hook ,如 How to gracefully handle the SIGKILL signal in Java 中所述不会阻止 Ctrl+c 传播给 child 。
最佳答案
Vladimir 给出了我们需要的提示! (抱歉,抢先了 Lukasz)
添加另一个脚本spawn_protect.sh
#!/bin/sh
LOG=$1
shift
nohup $* > $LOG 2>&1 &
并将经理更改为:
public class Runit {
public static void main(String args[]) throws IOException, InterruptedException {
Runtime.getRuntime().exec(args);
while (true) {
System.out.println("Kill me");
Thread.sleep(5000);
}
}
}
然后运行为:
java -classpath jar-with-dependencies.jar temp.exec.Runit spawn_protect.sh /tmp/runit.log runit.sh
现在 runit.sh 真正脱离了 JVM 进程!
关于java - 如何防止 ctrl+c 杀死 Java 中生成的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25012662/