2013-02-06 2 views
2
try { 

     String str; 
     Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run"); 
     InputStream isout = process.getInputStream(); 
     InputStreamReader isoutr = new InputStreamReader(isout); 
     BufferedReader brout = new BufferedReader(isoutr); 
     while ((str = brout.readLine()) != null) { 
      System.out.println(str); 
     } 

} catch (IOException e) { 
     e.printStackTrace(); 
} 

имеет проблемы с получением InputStream от процесса кода, , потому что, если я запустить сценарий оболочки из моего терминала он работает совершенно нормально, , но если я запустить сценарий как это, ул всегда нуль,Java Процесс не может получить InputStream через Runtime.getRuntime(). Exec()

Я использую этот код, чтобы получить выход Shell Script непосредственно в Java вместо написания вывода сценария в файле

есть ли любым другим способом достичь этого или как я могу решить проблему с использованием текущего подхода

+0

хороший вопрос, но довольно твердый. Это связано с блокировкой IO, которая всегда является болью.Однако есть библиотека под названием akka (http://akka.io/), которая претендует на преодоление таких проблем с блокировкой ввода-вывода. Я начал изучать его, и я должен был признать, что он тоже имеет свои ограничения ... – xhudik

+0

Вы уверены, что скрипт печатает на stdout, а не на stderr? – Dunes

+0

Есть ли что-нибудь возвращенное из process.getErrorStream()? – StarPinkER

ответ

4

Я думаю, что что-то возвращается через поток ошибок, так что вы можете попробовать, чтобы проверить что-то из Process.getErrorStream().

Вы также должны дождаться, пока созданный процесс не завершит вашу основную программу. Использовать Process.waitFor();

public class TestMain { 
    private static final String BASH_CMD = "bash"; 

    private static final String PROG = "/home/abhishek/workspace/Pro/run"; 

    private static final String[] CMD_ARRAY = { BASH_CMD , PROG }; 

    public static void main(String[] args) { 
     new Thread(new Runnable() { 
     public void run() { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        System.in)); 
      String command = null; 
      try { 
       while ((command = reader.readLine()) != null) { 
        System.out.println("Command Received:" + command); 
       } 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
       // failed to listening command 
      } 

     } 
     }).start(); 
     Process process = null; 
     try { 
     ProcessBuilder processBuilder = new ProcessBuilder(CMD_ARRAY); 
     process = processBuilder.start(); 
     InputStream inputStream = process.getInputStream(); 
     setUpStreamGobbler(inputStream, System.out); 

     InputStream errorStream = process.getErrorStream(); 
     setUpStreamGobbler(errorStream, System.err); 

     System.out.println("never returns"); 
     process.waitFor(); 
     } catch (IOException e) { 
     throw new RuntimeException(e); 
     } catch (InterruptedException e) { 
     throw new RuntimeException(e); 
     } 
    } 

    public static void setUpStreamGobbler(final InputStream is, final PrintStream ps) { 
     final InputStreamReader streamReader = new InputStreamReader(is); 
     new Thread(new Runnable() { 
     public void run() { 
      BufferedReader br = new BufferedReader(streamReader); 
      String line = null; 
      try { 
       while ((line = br.readLine()) != null) { 
        ps.println("process stream: " + line); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     }).start(); 
    } 
} 
0

Возможная проблема заключается к тому времени вы получить inputStram суб-процесс не готов

Попробуйте

Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run"); 
InputStream isout = process.getInputStream();  
process.waitFor() 
+0

'Runtime.getRuntime()' возвращает 'Runtime', а не процесс. @TechExchange, я бы рекомендовал вам удалить свой ответ, прежде чем получать downvotes. – AlexR

+0

@AlexR спасибо, отредактировал – TheWhiteRabbit

0

действие редактирования /home/abhishek/workspace/Pro/run если оболочку и добавьте следующую строку в верхней части.

#!/usr/bin/bash 

и предоставить необходимые разрешения на выполнение до /home/abhishek/workspace/Pro/run.

Затем используйте следующую строку

Process process = Runtime.getRuntime().exec("/home/abhishek/workspace/Pro/run"); 

Теперь, если запустить программу печатает все, что вы должны увидеть его на выходе.

+0

в linux, может возникнуть проблема с «./run» и «run», если вы выполняете программу. Линия вроде: Process process = Runtime.getRuntime(). Exec ("/ home/abhishek/workspace/Pro /./ run"); не помогло бы? – xhudik

+0

./ используется только для обозначения относительного пути. Но поскольку мы даем абсолютный путь, как это/home/abhishek/workspace/Pro/run, это не требуется. – shazin

+0

Как я уже сказал, я запускаю Shell Script, поэтому он не может быть ./run вообще, если что-то run.sh сделало бы проблему более очевидной. – Abhishek

0

Ваш код выглядит отлично. Поэтому я считаю, что проблема заключается либо в командной строке, которую вы используете (bash /home/abhishek/workspace/Pro/run), либо в самом скрипте.

Я предлагаю вам выполнить следующие действия:

  1. попытка запустить некоторые хорошо известную команду вместо вашего сценария. Например, pwd. Убедитесь, что ваш код, который читается из потока ввода, работает правильно.
  2. Теперь попробуйте упростить свой скрипт. Создайте скрипт run1, который просто запускает то же самое pwd. Теперь запустите этот скрипт из java и убедитесь, что он работает. Кстати, вам не нужно запускать его как bash yourscript. Вы можете напрямую запустить его без bash префикс
  3. Если все это работает, начинайте постепенно переходить от простого к реальному сценарию. Я верю, что вы найдете свою ошибку. Вероятно, ваш сценарий не может начинаться с некоторых проблем, связанных с окружающей средой.
+0

Эй, я просто понял, что мой вывод зависит от awk-программы. Я запускаю скрипт, он печатает вывод на терминале, но, однако, он не возвращает его процессу через среду выполнения, , так что есть способ переносить Вывод awk в переменную в оболочке ??? Я использовал его как 'vmstat | awk -f xx.awk' вывод выводится в файле awk с помощью оператора печати, Теперь мне нужно получить его в переменной в скрипте оболочки, , ваш совет помог мне, мне нужна последняя помощь. – Abhishek

0

Попробуйте что-то вроде этого:

String[] runCommand = new String[3]; 

runCommand[0] = "sh"; 
runCommand[1] = "-c"; 
runCommand[2] = "bash /home/abhishek/workspace/Pro/run"; 

Process process = runtime.exec(runCommand); 
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 
String line = reader.readLine(); 
reader.close(); 
Смежные вопросы