Java - как проверить, запущен ли другой (не Java) процесс в Linux - PullRequest
4 голосов
/ 08 декабря 2011

У меня странные проблемы с этим.

Мы используем менеджер виртуальных рабочих столов Xvfb и хотим убедиться, что он работает, прежде чем я продолжу.Используя чистую оболочку, я мог бы легко это сделать:

    ps -ef | grep Xvfb | grep -v grep

И это дает мне именно то, что мне нужно, одну строку, содержащую информацию о процедуре Xvfb.Далее я хочу включить это в свою Java-программу, проанализировать результаты и сохранить PID запущенного процесса Xvfb.Итак, я пытаюсь это сделать:

    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 () получает значение null каждый раз.

Я также пытался:

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

Просто захватить идентификатор процесса.Кроме того, не повезло.

Кто-нибудь еще испытывал это или знает, что я делаю неправильно?

Ответы [ 4 ]

5 голосов
/ 08 декабря 2011

Вы пытаетесь использовать "|"Это функция канала, специфичная для оболочки, поэтому вы не можете сделать это в процессе Java.Вы можете просто попытаться получить идентификатор процесса, используя pidof Xvfb.

3 голосов
/ 08 декабря 2011

Может быть Runtime.getRuntime().exec() пытается выполнить программу в том виде, как она есть в аргументе.То есть она запускает программу ps с аргументами -ef, |, grep и т. Д. И так, программа завершается ошибкой, потому что не понимает, что происходит.для запуска конвейерных команд вы должны явно вызвать оболочку:

Runtime.getRuntime().exec(new String[] {"sh", "-c", "ps -ef | grep Xvfb | grep -v grep"});
2 голосов
/ 08 декабря 2011

Когда вы выполняете командную строку напрямую, вы не получаете оболочку, а именно оболочка обрабатывает каналы.Итак, вы должны выполнить что-то вроде "/ bin / sh -e \" ps -ef |grep Xvfb |grep -v grep \ ""

1 голос
/ 04 сентября 2015

Есть много способов сделать это. Вы можете использовать java.lang.ProcessBuilder и "pgrep", чтобы получить идентификатор процесса (PID) с чем-то вроде: pgrep -fl java | awk {'print $1'}. Или, если вы работаете в Linux, вы можете запросить каталог /proc.

Я знаю, это кажется ужасным, непереносимым и даже плохо реализованным, я согласен. Но поскольку Java на самом деле работает в виртуальной машине, по какой-то абсурдной причине, которую я не могу понять после более чем 15-летнего опыта работы с JDK, по этой причине невозможно увидеть вещи вне пространства JVM, это действительно смешно, если вы думаю об этом. Вы можете делать все остальное, даже разветвляться и присоединяться к дочерним процессам ( это был ужасный способ многозадачности, когда мир не знал о потоков или pthreads , что за черт ! что происходит с Java?! :).

Это даст мне обширную дискуссию, которую я знаю, но в любом случае, есть очень хороший API, который я уже использовал в своих проектах, и он достаточно стабилен (это OSS, поэтому вам все равно нужно подвергать стресс-тестированию каждую версию, которую вы используете, прежде чем действительно доверять API ): https://github.com/jezhumble/javasysmon

JavaDoc: http://jezhumble.github.io/javasysmon/, ищи класс com.jezhumble.javasysmon.OsProcess, она добьется цели. Надеюсь, это помогло, удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...