2016-11-29 75 views
1

我有一個shell腳本,它有一些命令,其中一個命令期望在運行時輸入一些數據。我使用exec()方法運行這個shell腳本。目前,我正在手動輸入數據,如果它要求輸入。以下是我的代碼,在java程序中運行時從控制檯寫入和讀取數據

  Process p = Runtime.getRuntime().exec("myshellscript"); 

      BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 

      BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 

      // read the output from the command 
      System.out.println("Here is the standard output of the command:\n"); 
      while ((s = stdInput.readLine()) != null) { 
       System.out.println(s); 
      } 

      // read any errors from the attempted command 
      System.out.println("Here is the standard error of the command (if any):\n"); 
      while ((s = stdError.readLine()) != null) { 
       System.out.println(s); 
      } 

      System.exit(0); 

我想要做的就是輸入時控制檯預期的數據,應該由java程序進入,只是繼續我進一步的java程序。

回答

2

這是我做的:

  1. 創建兩個線程將從p.getInputStream()和p.getErrorStream()讀取,
  2. 寫入數據p.getOutputStream(),
  3. 等待兩個線程終止(與join()方法)

編輯:

public class Main { 
    private static final Logger LOG = Logger.getLogger(Main.class.getName()); 

    public static void main(String[] args) { 
     try { 
      Process p = Runtime.getRuntime().exec("myshellscript"); 
      Thread outHandler = new OutputHandler(p.getInputStream(), "UTF-8"); 
      outHandler.setDaemon(true); 
      outHandler.start(); 
      Thread errHandler = new OutputHandler(p.getErrorStream(), "UTF-8"); 
      errHandler.setDaemon(true); 
      errHandler.start(); 
      sendInput(p, "the input data", "UTF-8"); 
      int result = p.waitFor(); 
      outHandler.join(); 
      errHandler.join(); 
      System.out.println("exit code: " + result); 
     } catch (IOException ex) { 
      LOG.log(Level.SEVERE, null, ex); 
     } catch (InterruptedException ex) { 
      LOG.log(Level.SEVERE, null, ex); 
     } 
    }  

private void sendInput(Process process, String input, String encoding) 
     throws IOException { 

    try (OutputStream stream = process.getOutputStream(); 
      Writer writer = new OutputStreamWriter(
        stream, encoding == null ? "UTF-8" : encoding); 
      PrintWriter out = new PrintWriter(writer)) { 
     if (input != null) { 
      Reader reader = new StringReader(input); 
      BufferedReader in = new BufferedReader(reader); 
      String line = in.readLine(); 
      while (line != null) { 
       out.println(line); 
       line = in.readLine(); 
      } 
     } 
    } 
} 

    private static class OutputHandler extends Thread { 
     private BufferedReader in; 

     private OutputHandler(InputStream in, String encoding) 
       throws UnsupportedEncodingException { 
      this.in = new BufferedReader(new InputStreamReader(
        in, encoding == null ? "UTF-8" : encoding)); 
     } 

     @Override 
     public void run() { 
      try { 
       String s = in.readLine(); 
       while (s != null) { 
        System.out.println(s); 
        s = in.readLine(); 
       } 
      } catch (IOException ex) { 
       LOG.log(Level.SEVERE, null, ex); 
      } finally { 
       try { 
        in.close(); 
       } catch (IOException ex) { 
        LOG.log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
    } 
} 
+0

能否請你簡單介紹一下我對java新手的代碼,我從來沒有用過多線程。 –

+1

Here you go .... –

+0

請注意,如果您使用ProcessBuilder,則可以執行redirectErrorStream(true),並且只需要一個線程。 –