如何为多个操作系统管理ProcessBuilder?

时间:2014-08-20 19:21:21

标签: java windows cmd processbuilder

我想管理一个Shell执行器,我遇到一些Windows问题(不出意外)。

没有pb来检测OS,没有pb启动ProcessBuilder的进程,没有pb来编写StreamGobbler。 但是当我想用JUnit测试它时,我有一种奇怪的行为......

如果我把" cmd.exe"和" / C" Windows的命令,我的CMD脚本无法正常工作。没有一切是完美的。

问题出在哪里?

如果明天我想启动一个exe,我认为cmd.exe / c必须用start和path来完成。

My Shell执行人:

public static boolean execCmd(List<String> cmd, Map<String, String> env, File workingDir, GobblerListener gobblerListener) {
    boolean result = false;

    if (isWindows()) {
        //cmd.add(0, "cmd.exe");
        //cmd.add(1, "/C");
    } else if (isUnixSolaris()) {
        cmd.add(0, "/bin/ksh");
        cmd.add(1, "-c");
    } else {
        logger.debug(ResourceBundle.getBundle(bundleName).getString("system.env.unknown"));
        return result;
    }

    ProcessBuilder pb = new ProcessBuilder(cmd);
    Map<String, String> envp = pb.environment();
    for (Map.Entry<String, String> entry : env.entrySet()) {
        envp.put(entry.getKey(), entry.getValue());
    }
    if (workingDir != null) {
        pb.directory(workingDir);
    }
    pb.redirectErrorStream(true);

    Process p = null;
    try {
        p = pb.start();

        StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(),
                gobblerListener);
        outputGobbler.start();

        p.waitFor();
        outputGobbler.join();

        int exitValue = p.exitValue();
        result = (exitValue == 0 ? true : false);
    } catch (InterruptedException ex) {
        logger.error(ResourceBundle.getBundle(bundleName).getString(
                "system.env.exec.interrupted"));
    } catch (IOException e) {
        logger.error(
                ResourceBundle.getBundle(bundleName).getString(
                        "system.env.exec.exception"), e);
    } finally {
        if (p != null) {
            p.destroy();
        }
    }
    return result;
}

这是我的StreamGobbler:

public class StreamGobbler extends Thread {

    private static final Logger logger = LoggerFactory.getLogger(GobblerListener.class);

    public interface Listener {
        public void onLine(String line);
    }

    private Listener listener = null;
    private InputStream is = null;
    private BufferedReader reader = null;

    public StreamGobbler(InputStream is, Listener onLineListener) {
        this.is = is;
        this.listener = onLineListener;
    }

    @Override
    public void run() {
        // keep reading the InputStream until it ends (or an error occurs)
        try {
            reader = new BufferedReader(new InputStreamReader(is));
            try {
                String line = reader.readLine();
                while (line != null) {
                    if (listener != null && !line.trim().isEmpty())
                        listener.onLine(line);
                    line = reader.readLine();
                }
            } finally {
                reader.close();
            }
        } catch (IOException e) {
            logger.error("", e);
        }
    }
}

谢谢。

0 个答案:

没有答案