java - 如何使shell命令过程完成?
问题描述
我想在带有 Java 的 Linux 机器上执行特定的 shell 命令。所以我找到了来自 baeldung.com 的教程。
我的问题是,即使是示例命令(进程)也永远不会完成。
private static class StreamGobbler implements Runnable {
private InputStream inputStream;
private Consumer<String> consumer;
public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}
@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines()
.forEach(consumer);
}
}
boolean isWindows = System.getProperty("os.name")
.toLowerCase().startsWith("windows");
String homeDirectory = System.getProperty("user.home");
Process process;
if (isWindows) {
process = Runtime.getRuntime()
.exec(String.format("cmd.exe /c dir %s", homeDirectory));
} else {
process = Runtime.getRuntime()
.exec(String.format("sh -c ls %s", homeDirectory));
}
StreamGobbler streamGobbler =
new StreamGobbler(process.getInputStream(), System.out::println);
Executors.newSingleThreadExecutor().submit(streamGobbler);
int exitCode = process.waitFor();
assert exitCode == 0;
希望有人有想法。
解决方案
当您调用 时Executors.newSingleThreadExecutor()
,将启动一个后台线程。由于线程不是守护线程,JVM 不会终止,直到线程停止运行。这永远不会发生,因此您的 Java 程序会继续运行,即使main
线程已终止。
有多种修复方法:
不要使用执行器,只需启动一个线程,该线程将在
run()
方法结束时StreamGobbler
结束。StreamGobbler streamGobbler = ... new Thread(streamGobbler).start(); int exitCode = process.waitFor();
完成后关闭执行程序。
StreamGobbler streamGobbler = ... ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(streamGobbler); int exitCode = process.waitFor(); executor.shutdown();