linux—java命令行子进程的“sudo”和“kill”之间奇怪的交互

kuhbmx9i  于 2021-07-07  发布在  Java
关注(0)|答案(0)|浏览(333)

如果使用 sudo ,那么出于某种原因,它不能从同一个java程序中终止,即使使用 sudo kill <subprocess_pid> .
下面的java代码启动 rsync 子流程 p0 使用 Runtime.exec . 命令的前缀为 sudo . 然后它等待2秒钟,并试图杀死 p0 通过使用以下命令启动另一个子进程 "sudo kill -2 " + p0.pid() .
但是,此代码无法杀死 rsync 子流程(如果两者都是) rsync 以及 kill 启动时使用 sudo . 如果你取而代之的是 "sudo" 参数,然后 kill 成功杀戮 rsync .
有趣的是,两者都有 "sudo" 前缀就位,运行完全相同 sudo kill -2 <pid> 命令行的命令成功地杀死了 rsync 过程。只有当 sudo kill 命令是从java运行的,它失败了。然而 sudo kill 子进程返回退出代码 0 在java中,表示它认为自己成功了。然而,信号从未传递到 rsync 过程。
问题:
为什么java不能sudo杀死它sudo启动的子进程(如果父进程作为根进程运行,则也是如此。)
信号来自哪里 sudo kill 在这个例子中,命令丢失了吗(信号从未真正传递到 rsync 过程。)
代码:(替换 /path/to/SomeLargeFile 可以复制到的大文件的路径 /tmp )

public class TestKill {
    public static void main(String[] args) throws Exception {
        // Launch "sudo rsync" process, and print pid
        Process p0 = Runtime.getRuntime().exec(new String[] {
                "sudo", "rsync", "-I", "--info=progress2",
                "/path/to/SomeLargeFile", "/tmp" });
        System.out.println("p0 pid: " + p0.pid());

        // Display stdout from p0
        new Thread(() -> {
            try (var r = new BufferedReader(new InputStreamReader(
                        p0.getInputStream()))) {
                for (String line; (line = r.readLine()) != null;) {
                    System.out.println("p0 stdout line: " + line);
                }
            } catch (IOException e) {
            }
        }).start();

        // Try killing p0 after 2 seconds using "sudo kill"
        Thread.sleep(2000);
        System.out.println("sudo kill -2 " + p0.pid() + " : exit code = "
                + Runtime.getRuntime().exec(new String[] {
                          "sudo", "kill", "-2", "" + p0.pid() })
                    .waitFor());

        // Wait for process termination
        while (p0.isAlive()) {
            System.out.println("p0 is still alive");
            Thread.sleep(1000);
        }
        System.out.println("Finished");
    }
}

运行此代码时的输出:

pid: 3733566
p0 stdout line: 
p0 stdout line:          32,768   0%    0.00kB/s    0:00:00  
p0 stdout line:     614,924,288   1%  586.41MB/s    0:01:19  
sudo kill -2 3733566 : exit code = 0
p0 is still alive
p0 stdout line:   1,215,922,176   2%  580.07MB/s    0:01:18  
p0 is still alive
p0 stdout line:   1,840,513,024   3%  585.46MB/s    0:01:17  
p0 is still alive
p0 stdout line:   2,445,377,536   5%  583.45MB/s    0:01:16  
p0 is still alive
p0 stdout line:   3,069,902,848   6%  585.75MB/s    0:01:15  
p0 is still alive
p0 stdout line:   3,708,092,416   7%  594.63MB/s    0:01:12  
p0 is still alive
p0 stdout line:   4,322,394,112   8%  592.17MB/s    0:01:12  
p0 is still alive
[... until "sudo kill -2 3733566" is re-run manually from the terminal: ...]
p0 is still alive
p0 is still alive
p0 stdout line:   8,657,043,456  17%  591.61MB/s    0:01:05  
Finished

如果两个都删除,则输出 "sudo" 前缀(在2或3秒后正确终止):

pid: 3732672
p0 stdout line: 
p0 stdout line:          32,768   0%    0.00kB/s    0:00:00  
p0 stdout line:     590,020,608   1%  562.66MB/s    0:01:22  
kill -2 3732672 : exit code = 0
p0 is still alive
p0 stdout line:   1,225,293,824   2%  584.54MB/s    0:01:18  
Finished

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题