简体   繁体   English

从Java运行Shell脚本

[英]Running shell script from Java

I am trying to run some shell scripts for Java by using commons exec package and clear the STDOUT & STDERR buffers by using PumpStreamHandler. 我正在尝试使用commons exec程序包运行Java的一些Shell脚本,并使用PumpStreamHandler清除STDOUT和STDERR缓冲区。 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 up. 我的猜测是,PumpStramHandle可能正在读取流的末尾,因为一段时间内没有任何内容放入流中,之后缓冲区已满。

Is there any better way to get across this problem? 有没有更好的方法来解决这个问题?

Extract the script/command being executed and run it yourself in a shell. 提取正在执行的脚本/命令,然后在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. 当运行通过某种其他语言(c,c ++,python java等)“执行”的事物并且事物开始出现“错误”时,这应该是第一步。

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM