Java запускает команду bash при подаче ввода и получении вывода

Мне нужно написать код Java, который запускает внешний процесс. Этот процесс получает строку ввода из стандартного ввода и выдает строку вывода на стандартный вывод.

Код, который я написал, выглядит следующим образом

try
{            
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec("./" + args[0]);
    Process proc2 = rt.exec(c);
    int exitVal = proc2.exitValue();
    System.out.println("Process exitValue: " + exitVal);
} 
catch (Throwable t){
}

Где args[0] — внешний процесс, а c — ввод (строка), который мне нужно передать процессу. Если бы он работал правильно, я бы получил exitVal=0, а не ничего. Кроме того, я действительно хочу напечатать вывод внешнего процесса (в данном примере это будет «6»).


person Athanasia Notta    schedule 28.03.2012    source источник
comment
catch (Throwable t){}... никогда не делайте этого javapractices.com/topic/TopicAction.do?Id =16   -  person artbristol    schedule 28.03.2012


Ответы (3)


Вы должны использовать getInputStream() и getOutputStream() в процессе, чтобы сообщить о нем, см. javadocs.

Если вы не прочитаете все данные из процесса, он может зависнуть и даже зайти в тупик. Краткое введение в распространенные проблемы см. в этой записи блога. По крайней мере, вы должны считывать все данные из вывода процесса.

person wds    schedule 28.03.2012

Вы не можете «ничего не получить». Метод exitValue() возвращает примитивный тип, поэтому он даже не может быть нулевым. Но этот метод может застрять однако. Это происходит потому, что ваш процесс все еще работает.

Возможно ли, что он работает, потому что вы его не "кормили"? В этом случае вам остается только вызвать proc2.getOutputStream() и написать в этот поток то, что вам нужно. Если вы хотите прочитать вывод процесса, используйте proc2.getInputStream() и прочитайте из потока.

Кстати, взгляните на ProcessBuilder. Он предоставляет лучший, более "объектно-ориентированный" API, чем простой Runtime.exec().

person AlexR    schedule 28.03.2012
comment
Спасибо за ваш ответ! По-прежнему безуспешно с использованием ProcessBuilder :/ Проблема остается той же... Исполняемый файл работает следующим образом: вы запускаете его (Enter), а затем ждете строку (вы вводите строку -> Enter).. В основном это один процесс, мне нужен только способ сообщить этому процессу, что он ожидает stdin. - person Athanasia Notta; 29.03.2012

Вы можете передать ввод программы с перенаправлением '‹':

{
  Process p = Runtime.getRuntime().exec("wc < pom.xml");
  p.waitFor();
  System.out.println(p.exitValue());
  BufferedReader bri = new BufferedReader
    (new InputStreamReader(p.getInputStream()));
  String line;
  while ((line = bri.readLine()) != null) {
    System.out.println(line);
  }
  bri.close();
}
person wytten    schedule 28.03.2012
comment
Спасибо за ваш ответ! Дело в том, что я не хочу кормить свой исполняемый файл файлом, а строкой. - person Athanasia Notta; 29.03.2012