Java - 如何检查Linux上是否正在运行另一个(非Java)进程

时间:2011-12-07 21:09:26

标签: java linux unix process grep

我有一些奇怪的问题。

我们正在使用Xvfb虚拟桌面管理器,并希望在继续之前确保它正在运行。使用纯shell,我可以轻松地做到这一点:

    ps -ef | grep Xvfb | grep -v grep

这正是我所需要的,一行包含有关Xvfb proc的信息。接下来,我想将它合并到我的Java程序中并解析结果并存储正在运行的Xvfb进程的PID。我正在尝试这个:

    String line;
    try {
      Process p = Runtime.getRuntime().exec("ps -ef | grep Xvfb | grep -v grep");
      BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
      while ((line = input.readLine()) != null)
      {
        System.out.println(line);
      }
    } catch (Exception err) {
      System.out.println(err);
    }

奇怪的是,如果我使用“ps -ef”,当我运行我的应用程序时,我会收到一个大量的进程转储到我的控制台。但是,如果我使用| grep缩小返回的进程列表,我得到零结果。 input.readLine()每次都为空。

我也尝试过:

    ps -ef | grep Xvfb | grep -v grep | awk {'print $2'}

要抓住进程ID。而且,没有运气。

有没有其他人经历过这个或知道我做错了什么?

4 个答案:

答案 0 :(得分:5)

你正在尝试使用“|”这是一个特定于shell的管道函数,因此您无法在Java进程中执行此操作。您可以尝试使用pidof Xvfb来获取进程ID。

答案 1 :(得分:3)

也许Runtime.getRuntime().exec()尝试执行程序中的程序。也就是说,它使用参数ps-ef|等运行程序grep。因此,程序失败,因为它无法理解正在发生的事情。< / p>

如果你需要运行管道命令,你应该明确地调用shell:

Runtime.getRuntime().exec(new String[] {"sh", "-c", "ps -ef | grep Xvfb | grep -v grep"});

答案 2 :(得分:2)

当你直接执行你的命令字符串时,你没有得到一个shell,它是处理管道的shell。所以,你会执行像“/ bin / sh -e \”ps -ef |这样的东西grep Xvfb | grep -v grep \“”

答案 3 :(得分:1)

有很多方法可以做到这一点。您可以使用java.lang.ProcessBuilder和“pgrep”来获取进程ID(PID),例如:pgrep -fl java | awk {'print $1'}。或者,如果您在Linux下运行,则可以查询/proc目录。

我知道,这似乎很糟糕,而且不便携,甚至执行不力,我同意。但是因为Java实际上是在VM中运行的,出于一些荒谬的原因,我在JDK工作超过15年之后无法弄清楚,这就是为什么不可能看到JVM空间以外的东西,如果你真的很荒谬想一想。你可以做其他所有事情,甚至分叉和加入子进程(当世界不知道线程 pthreads 时,那些是多任务的可怕方式,什么地狱!Java正在发生什么?! :)。

这将给出我所知道的一个巨大的讨论,但无论如何,我已经在我的项目中使用了一个非常好的API并且它足够稳定(它是OSS所以你仍然需要在真正信任API之前对你使用的每个版本进行压力测试):https://github.com/jezhumble/javasysmon

JavaDoc:http://jezhumble.github.io/javasysmon/,搜索班级com.jezhumble.javasysmon.OsProcess,她会做的伎俩。希望它有所帮助,祝你好运。