【问题标题】:Java - how to check whether another (non-Java) process is running on LinuxJava - 如何检查 Linux 上是否正在运行另一个(非 Java)进程
【发布时间】:2012-01-15 09:26:16
【问题描述】:

我遇到了一些奇怪的问题。

我们正在使用 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。另外,运气不好。

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

【问题讨论】:

  • 使用 pgrep 代替 ps 和 2 个 greps

标签: java linux unix process grep


【解决方案1】:

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

我知道,我同意这看起来很糟糕,而且不可移植,甚至实施得很差。但是因为 Java 实际上是在 VM 中运行的,出于某种荒谬的原因,我在 JDK 工作超过 15 年之后我无法真正弄清楚,这就是为什么无法看到 JVM 空间之外的东西,如果你真的很荒谬想想看。你可以做任何其他事情,甚至 fork 和 join 子进程(当世界不知道 threadspthreads 时,这是一种可怕的多任务处理方式,什么见鬼!Java 怎么了?! :)。

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

JavaDoc:http://jezhumble.github.io/javasysmon/,搜索类com.jezhumble.javasysmon.OsProcess,她会成功的。希望对您有所帮助,祝您好运。

【讨论】:

    【解决方案2】:

    也许Runtime.getRuntime().exec() 尝试按照参数中的方式执行程序。也就是说,它使用参数-ef|grep 等运行程序ps。因此,程序失败,因为它不了解发生了什么。

    如果你需要运行管道命令,你应该显式调用 shell:

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

    【讨论】:

      【解决方案3】:

      当你直接执行你的命令字符串时,你不会得到一个 shell,它是处理管道的 shell。所以,你会执行类似 "/bin/sh -e \"ps -ef | grep Xvfb | grep -v grep\""

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • @torgis,不客气!不久前我有一个类似的问题。很高兴我的痛苦得到了回报。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多