我想管理一个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);
}
}
}
谢谢。