在Java中,我使用Runtime.exec()启动一个新进程,而该进程又产生了几个子进程。
我希望能够杀死所有进程,并且以前一直尝试使用process.destroy()
和process.destroyForcibly()
-但是docs说destroyForcibly()
只是调用{{1 }}的默认实现中,destroy()
可能不会杀死所有子进程(我已经尝试过,显然也不会杀死子进程)。
我现在正在尝试另一种方法,使用建议的方法here查找父进程的PID,然后反复调用destroy()
遍历子进程的PID,然后将其全部杀死使用ps
。 (它只需要在Linux上运行即可。)
我已经管理好第一位-查找PID,并且正在尝试以下命令来调用ps以获取子PID:
kill
不幸的是,上面的第二行抛出了IOException,带有以下消息:String command = "/bin/ps --ppid " + pid;
Process process = new ProcessBuilder(command).start();
process.waitFor();
如果我将其直接粘贴到Ubuntu 16.04的终端中,该命令运行正常。
任何想法都会非常感激。
谢谢
答案 0 :(得分:0)
以这种方式调用您希望运行的命令总是注定会失败。
由于Process
不能有效地运行Shell会话,因此该命令基本上已移交给底层OS来运行。这意味着它将失败,因为要执行的程序的路径(在本例中为ps
)不是完整的路径,因此会出现错误。
此外,测试命令是否可以在终端上正常运行。使用终端包含对具有正确路径等的活动登录用户执行操作的概念。尽管通过Process
运行命令时,上述所有情况都不是,但没有考虑到这些。 / p>
此外,您还需要考虑实际的Java应用程序可能在具有不同权限,路径等的不同用户下运行的情况。
为解决此问题,您只需执行以下任一操作即可:
1)使用完整路径调用您的ps
命令(仍然不确定它是否可行)
2)将创建Process
对象的方式更改为:p = new ProcessBuilder("bash", "-c", command).start();
第二个将有效地运行bash会话,将ps
命令作为参数传递,从而获得所需的结果。
答案 1 :(得分:0)
http://commons.apache.org/proper/commons-exec/tutorial.html
```
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
```