如何防止ctrl + c在Java中杀死产生的进程
[NB。 这与我如何从Java程序启动完全独立的进程有关? 但不同]
我希望能够从一个“管理器”Java进程中产生外部进程(shell脚本),当JVM被终止时它应该继续运行 - 但是当我杀死父Java程序时,孩子也被杀死了(注意,如果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。
编辑1:将exec更改为
Runtime.getRuntime().exec("/usr/bin/nohup " + args[0]);
没有帮助。
编辑2:按照如何在Java中正常处理SIGKILL信号中所述添加关闭挂钩不会停止将Ctrl + c传播给子节点。
弗拉基米尔给了我们需要的提示! (对不起,击败卢卡斯)
添加另一个脚本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进程!
在Linux中,如果你启动另一个进程,它是你的孩子,你是他的父母。 如果父母遇害,所有的孩子都会被杀害,他们的孩子也会被杀害(这是一种可怕的暴行)。
你需要的是启动一个当你退出程序时不会被杀死的进程。 所以,你需要生下不是你自己的孩子。 例如,在这里描述的方法如下:Linux:关闭SSH客户端后禁止后台进程停止,例如使用screen
实用程序。
你必须把它变成一个守护进程。 不要害怕这不是一部恐怖电影。 只需要将您的进程从控制终端会话中分离出来。 我一直以相反的方式做它:启动Java的shell脚本。
这里是一个解释:
http://en.wikipedia.org/wiki/Daemon_(computing)
你也可以使用“jvm shutdown hooks”,但它们在某些情况下不起作用。
链接地址: http://www.djcxy.com/p/80645.html上一篇: How to prevent ctrl+c killing spawned processes in Java
下一篇: based DLL in a non