开发者

Running shell script from Java

开发者 https://www.devze.com 2023-03-07 06:34 出处:网络
I am trying to run some shell scripts for Java by using commons exec package and clear the STDOUT & STDERR buffers by using PumpStreamHandler. Most of the scripts run fine without any problems but

I am trying to run some shell scripts for Java by using commons exec package and clear the STDOUT & STDERR buffers by using PumpStreamHandler. Most of the scripts run fine without any problems but some of them hangs.

Particularly those scripts that takes some time to return. My guess is that the PumpStramHandle might be reading end of stream as there is nothing put on the stream for a while and after that the buffers fill 开发者_C百科up.

Is there any better way to get across this problem?


Extract the script/command being executed and run it yourself in a shell. When running things that are 'exec'd through some other language(c,c++, python java etc) and things start going 'wrong' this should be the first step.

You find all sorts of things going on. Scripts that stop and prompt for input(big source of hangups) errors that don't parse correctly, seg faults, files not found.


To expand on the first answer about running the commands directly to test, you can test your hypothesis with a simple script that sleeps for a while before returning output. If you can't test your command, test your idea.

#!/bin/bash

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


Not the best solution. But does what I need. :)

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;
    }
}

Usage:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号