Как использовать символ трубы через exec в Java [дубликат]

этот вопрос уже есть ответ здесь:

я использую следующий код, чтобы получить подробную информацию о всех процессах, запущенных в системе:

Process p = Runtime.getRuntime().exec("ps aux");
BufferedReader stdInput = new BufferedReader(new 
             InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new 
             InputStreamReader(p.getErrorStream()));

Я хочу, чтобы фильтр ps aux вниз с символом трубы, поэтому я использую это:

Process p = Runtime.getRuntime().exec("ps aux | grep java");

он переходит в ErrorStream. Позже я заметил, что символ трубы ( | ) используется как побитовый оператор inclusive или в Java. Поэтому я использовал обратную косую черту перед символом трубы, как показано ниже:

Process p = Runtime.getRuntime().exec("ps aux | grep java"); 

но снова он переходит в ErrorStream. Как я могу бежать ps aux | grep java через exec на Java?

4 ответов


труба-это функция оболочки - вы не используете оболочку, вы выполняете процесс (ps).

но на самом деле, почему вы хотите это сделать? Ты говоришь:

"выполнить ps, затем передать его вывод в другую программу (grep) и извлечь то, что мне нужно"

вам просто нужно извлечь то, что вы хотите на выходе ps. Используйте Matcher и обратите внимание только на строки, которые включают java из своего InputStream

http://download.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html


Ну, если вы хотите использовать трубы в процессе, который вы выполняете, тогда вам нужно запустить оболочку, такую как bash, и дать ps и grep в командной строке этой оболочке:

bash -c "echo $PATH"

попробуйте это понять, что я имею в виду, а затем используйте это:

bash -c "ps axu | grep PATTERN"

чтобы понять, как вам нужно настроить java.во время выполнения.Процесс.

Я не пробовал, но предполагаю следующее:

Process p = Runtime.getRuntime().exec(new String[] { "bash", "-c", "ps axu | grep PATTERN" });

надеюсь, что это поможет; D


  1. вам нужно отделить команду от ее аргументов при вызове exec, например .exec(new String[] { "ps", "aux" }) (не exec("ps aux")). Когда вам нужно передать аргументы, вам нужно вызвать String [] version-первый элемент String[] - команда, остальные-аргументы.

  2. необходимо отправить содержимое выходного потока первой команды во входной поток второй команды. Я использовал Apache commons IOUtils сделать это с легкостью.

  3. вы должны закрыть входной поток grep вызов, в противном случае он будет висеть в ожидании конца ввода.

С этими изменениями в месте, этот код делает то, что вы хотите:

import org.apache.commons.io.IOUtils;

public static void main(String[] args) throws Exception
{
    Process p1 = Runtime.getRuntime().exec(new String[] { "ps", "aux" });
    InputStream input = p1.getInputStream();
    Process p2 = Runtime.getRuntime().exec(new String[] { "grep", "java" });
    OutputStream output = p2.getOutputStream();
    IOUtils.copy(input, output);
    output.close(); // signals grep to finish
    List<String> result = IOUtils.readLines(p2.getInputStream());
    System.out.println(result);
}

Извините, я не знаю, как правильно передавать результаты из одной команды в другую, но если все, что вы хотите, это процесс Java, JDK поставляется с программой под названием jps что делает именно это. Попробуйте это:

jps -l