我想通過使用commons exec包運行一些Java腳本,並使用PumpStreamHandler清除STDOUT & STDERR緩衝區。大多數腳本運行正常,沒有任何問題,但其中一些掛起。從Java運行shell腳本
特別是那些需要一段時間才能返回的腳本。我的猜測是,PumpStramHandle可能正在讀取流結束,因爲暫時沒有任何東西放在流上,然後緩衝區填滿。
有沒有更好的方法來解決這個問題?
我想通過使用commons exec包運行一些Java腳本,並使用PumpStreamHandler清除STDOUT & STDERR緩衝區。大多數腳本運行正常,沒有任何問題,但其中一些掛起。從Java運行shell腳本
特別是那些需要一段時間才能返回的腳本。我的猜測是,PumpStramHandle可能正在讀取流結束,因爲暫時沒有任何東西放在流上,然後緩衝區填滿。
有沒有更好的方法來解決這個問題?
不是最好的解決方案。但是做我需要的。 :)
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();
提取正在執行的腳本/命令,並自己在shell中運行它。當通過其他語言(c,C++,python java等)運行'exec'的東西時,事情開始發生'錯誤',這應該是第一步。
你會發現各種各樣的事情正在進行。腳本停止並提示輸入(hangup的大來源)錯誤,不能正確解析,seg故障,找不到文件。
爲了擴展第一個直接運行命令來測試的答案,你可以用一個簡單的腳本來測試你的假設,該腳本在返回輸出之前會休眠一段時間。如果你 不能測試你的命令,請測試你的想法。
#!/bin/bash
sleep 60;
echo "if you are patient, here is your response"
我承認你是對的。但在這種情況下,這確實不是一種選擇。 – 2011-05-19 19:23:41