2011-05-19 214 views
0

我想通過使用commons exec包運行一些Java腳本,並使用PumpStreamHandler清除STDOUT & STDERR緩衝區。大多數腳本運行正常,沒有任何問題,但其中一些掛起。從Java運行shell腳本

特別是那些需要一段時間才能返回的腳本。我的猜測是,PumpStramHandle可能正在讀取流結束,因爲暫時沒有任何東西放在流上,然後緩衝區填滿。

有沒有更好的方法來解決這個問題?

回答

0

不是最好的解決方案。但是做我需要的。 :)

class OSCommandLogger extends Thread { 
    private static final Logger logger = Logger.getLogger(OSCommandLogger.class); 
    private volatile boolean done = false; 
    private final String name; 
    // Each process is associated with an error and output stream 
    private final BufferedReader outputReader; 
    private final BufferedReader errorReader; 
    private final Logger log; 

    /** 
    * Reads the output & error streams of the processes and writes them to 
    * specified log 
    * 
    * @param p 
    * @param name 
    * @param log 
    */ 
    OSCommandLogger(Process p, String name, Logger log) { 
     // Create readers 
     outputReader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     errorReader = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
     this.log = log; 
     if (name != null) 
      this.name = name; 
     else 
      this.name = "OSCommandStreamsLogger"; 
    } 

    private void logLine(BufferedReader reader, boolean isError) { 
     try { 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       if (log != null && log.isDebugEnabled()) { 
        if (!isError) 
         log.debug("[OuputStream] " + line); 
        else 
         log.warn("[ErrorStream] " + line); 
       } else 
        logger.debug(line); 
      } 
     } catch (Exception ex) { 
      if (log != null) 
       log.error(name + ":" + "Error while reading command process stream", ex); 
     } 
    } 

    public void run() { 
     while (!done) { 
      logLine(outputReader, false); 
      logLine(errorReader, true); 

      try { 
       // Sleep for a while before reading the next lines 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       log.debug("Done with command"); 
      } 
     } 

     // Process is done. Close all the streams 
     try { 
      logLine(outputReader, false); 
      outputReader.close(); 

      logLine(errorReader, true); 
      errorReader.close(); 
      if (log != null && log.isDebugEnabled()) 
       log.debug(name + ": Closed output/ error Streams."); 

     } catch (IOException ie) { 
      if (log != null) 
       log.error(name + ":" + "Error while reading command process stream", ie); 
     } 
    } 

    public void stopLoggers() { 
     if (log != null && log.isDebugEnabled()) 
      log.debug(name + ":Stop loggers"); 
     this.done = true; 
    } 
} 

用法:

Process p = Runtime.getRuntime().exec("Command"); 
OSCommandLogger logger = new OSCommandLogger(p, "Command", log); 

// Start the thread using thread pool 
threadExec.executeRunnable(logger); 
int exitValue = p.waitFor(); // Wait till the process is finished 

// Required to stop the logger threads 
logger.stopLoggers(); 
logger.interrupt(); 
0

提取正在執行的腳本/命令,並自己在shell中運行它。當通過其他語言(c,C++,python java等)運行'exec'的東西時,事情開始發生'錯誤',這應該是第一步。

你會發現各種各樣的事情正在進行。腳本停止並提示輸入(hangup的大來源)錯誤,不能正確解析,seg故障,找不到文件。

+0

我承認你是對的。但在這種情況下,這確實不是一種選擇。 – 2011-05-19 19:23:41

0

爲了擴展第一個直接運行命令來測試的答案,你可以用一個簡單的腳本來測試你的假設,該腳本在返回輸出之前會休眠一段時間。如果你 不能測試你的命令,請測試你的想法。

#!/bin/bash 

sleep 60; 
echo "if you are patient, here is your response"