如何防止ctrl c在Java中查杀生成的进程

前端之家收集整理的这篇文章主要介绍了如何防止ctrl c在Java中查杀生成的进程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
[NB.这与 How do I launch a completely independent process from a Java program?有关但不同]

我希望能够从一个“管理器”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程序中执行Java程序时,外部程序也会被杀死,这不是我想要的.

我在Ubuntu上使用OpenJDK 1.6.

Edit1:将exec更改为

Runtime.getRuntime().exec("/usr/bin/nohup " +  args[0]);

没有帮助.

Edit2:如How to gracefully handle the SIGKILL signal in Java中所述添加关闭挂钩不会阻止Ctrl c传播到子节点.

解决方法

弗拉基米尔给出了我们需要的暗示! (对不起,打败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进程!

猜你在找的C&C++相关文章