0

commons execパッケージを使用してJavaのシェルスクリプトを実行し、PumpStreamHandlerを使用してSTDOUTおよびSTDERRバッファーをクリアしようとしています。ほとんどのスクリプトは問題なく正常に実行されますが、一部のスクリプトはハングします。

特に、戻るのに時間がかかるスクリプト。私の推測では、PumpStramHandleは、しばらくの間ストリームに何も置かれず、その後バッファがいっぱいになるため、ストリームの終わりを読み取っている可能性があります。

この問題を解決するためのより良い方法はありますか?

4

3 に答える 3

0

コマンドを直接実行してテストすることに関する最初の回答を拡張するために、出力を返す前にしばらくスリープする単純なスクリプトを使用して仮説をテストできます。コマンドをテストできない場合は、アイデアをテストしてください。

#!/bin/bash

sleep 60;
echo "if  you are patient, here is your response"
于 2011-05-19T21:06:09.507 に答える
0

実行中のスクリプト/コマンドを抽出し、シェルで自分で実行します。'他の言語(c、c ++、python javaなど)で実行されたものを実行し、'間違った'状態になり始めた場合、これが最初のステップになるはずです。

あなたはいろいろなことが起こっているのを見つけます。正しく解析されない入力(ハングアップの大きな原因)エラー、セグメンテーション違反、ファイルが見つからないことを停止して要求するスクリプト。

于 2011-05-19T18:39:02.370 に答える
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();
于 2011-07-26T09:22:19.833 に答える