如何从Java应用程序中获取Linux中正在运行的进程的准确列表?

时间:2017-08-20 18:43:04

标签: java linux process

我正在制作一个应用程序,其中一个要求是能够搜索其他正在运行的应用程序的进程并在需要时终止它们。

我试过" jps "它与JDK一起提供,这正是我所需要的。应用程序的进程ID,以及应用程序的真实名称。使用这个我可以通过进程id杀死,以及按名称匹配我实际需要终止的进程,而不会终止错误的进程。遗憾的是,并非所有此应用程序的最终用户都拥有JDK,因此jps不可靠。我需要另一种方法来做到这一点。

我尝试了许多" ps"似乎无法正常工作的命令。例如,我正在使用

ps -e -o command

这给了我......

line:  2729 ?        00:02:53 chrome
line:  2824 ?        00:00:00 cat
line:  2825 ?        00:00:00 cat
line:  2945 ?        00:00:00 chrome
line:  2946 ?        00:00:00 nacl_helper
line:  2959 ?        00:00:00 chrome
line:  2962 ?        00:00:00 gconfd-2
line:  3120 ?        00:07:39 chrome
line:  3179 ?        00:00:00 chrome
line:  3296 ?        00:00:44 chrome
line:  3500 ?        00:00:00 bash
line:  3751 ?        00:07:27 java
line:  3832 ?        00:00:00 file-roller
line:  4832 ?        00:00:23 chrome
line:  4883 ?        00:00:03 gnome-terminal-
line:  6085 ?        00:00:51 chrome
line:  6380 ?        00:00:06 chrome
line:  7865 ?        00:00:16 chrome
line:  8961 ?        00:00:06 chrome
line:  9404 ?        00:00:43 chrome
line: 10344 ?        00:00:02 chrome
line: 10761 ?        00:00:05 chrome
line: 11158 ?        00:00:00 java
line: 11193 ?        00:00:00 sh

这对我没有帮助,因为它没有显示进程名称,而且它似乎也不准确。当我从终端运行我的java应用程序然后重新运行程序时,正在运行的应用程序不会发生变化,我希望看到添加额外的进程。

来自Java我目前正在使用

/bin/sh -c ps -e -o command

有没有办法做到这一点?或者某种方式来隔离jps可执行文件,以便我可以将它打包到我的项目中并在便携式庄园中使用它?

从JDK运行 jps 时,我得到此输出

3751 Main
14015 Jps
**11503** updater.jar

当我从我的机器终端运行ps -ef时,我得到了这个输出

root     10519     2  0 20:25 ?        00:00:00 [kworker/5:0]
root     11156     2  0 20:40 ?        00:00:00 [kworker/7:1]
root   **11503**  6170  0 20:49 pts/1    00:00:01 java -jar game/updater.jar /home
root   13031  2959  0 21:15 ?        00:00:13 /opt/google/chrome/chrome --type
root     13071     2  0 21:19 ?        00:00:00 [kworker/4:2]

当我从我的Java应用程序运行 ps -ef 时,我得到以下内容,并且进程ID 11503 无处可见......

Process process = Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", "ps", "-ef" });

line:  7865 ?        00:00:17 chrome
line:  8961 ?        00:00:06 chrome
line:  9404 ?        00:00:43 chrome
line: 10344 ?        00:00:03 chrome
line: 13031 ?        00:00:09 chrome
line: 13098 ?        00:00:15 chrome
line: 13961 ?        00:00:00 java
line: 13996 ?        00:00:00 sh
line: 13997 ?        00:00:00 ps

问题是命令中的/ bin / sh -c。删除这个给了我正确的输出,虽然我仍然认为jps是一个更好的解决方案(jps可以被隔离,但最终大小是~100mb)

3 个答案:

答案 0 :(得分:0)

这里有两个非常不同的东西:

  1. 运行ps命令的内容/方式。我个人认为:ps -ef - 以“完整”格式列出所有进程。有关详细信息,请参阅this
  2. 如何调用和读取java的输出。为此,请参阅here例如。

答案 1 :(得分:0)

由于这似乎是Linux或类似的,我认为比捕获“ps”的输出更好的方法是用数字文件名枚举/ proc中的所有文件,并检查每个文件中的文件cmdline 。也就是说,所有各种/ proc / NNNN / cmdline文件。这不需要运行ps或任何其他外部进程,其输出可能在系统之间略有不同。它提供了对操作系统所有信息的访问 - 您不必依赖“ps”完全按照您的意愿行事。

此外,您不必依赖Runtime.exec()及其所有细微的恶意。

答案 2 :(得分:0)

虽然这个问题的答案似乎解决了一个问题,但最终并没有解决我的问题。

问题是我传递的命令

Process process = Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", "ps", "-ef" });

应删除/ bin / sh -c并返回正确的进程。

Process process = Runtime.getRuntime().exec(new String[] { "ps", "-ef" });

此外,我还致力于使用JDK提供的jcmd应用程序,因为它提供了我正在寻找的以及跨平台支持的内容。