是否有任何理智的方法从Java运行忽略STDOUT和STDERR的系统命令?例如,当我尝试以下操作时:
Process p = Runtime.getRuntime().exec("some_executable_path param1 param2 >NUL 2>&1");
Java尝试解析命令,并最终转义参数(例如,阻止输出被重定向)。如果我没有重定向STDOUT / STDERR,则缓冲区会填满并阻止系统调用退出。以下是我想要的,但是非常麻烦并且创建昂贵的资源只是为了抛弃系统调用的输出:
ProcessBuilder pb = new ProcessBuilder("some_executable_path", "param1", "param2");
pb.redirectErrorStream(true);
final Process p = pb.start();
final Thread redirectToNull = new Thread(() -> {
final InputStream stdout = process.getInputStream();
try {
while (stdout.read() != -1);
} catch (final Exception e) {
// Don't care
}
}, "Output Consumer Thread");
redirectToNull.setDaemon(true);
redirectToNull.start();
我意识到Java设计团队被称为自虐,但这很荒谬。我更愿意提供一个批处理或Perl脚本,用我的应用程序包装系统调用,而不是使用上面的代码。必须有一种更简单的方法来实现这一目标。
所以问题是,是否有任何理智的方法从Java中运行系统命令并忽略打印到STDOUT / STDERR的输出?
答案 0 :(得分:5)
并不是说Java'阻止'重定向,它只是没有肯定地做,而且你的程序也没有。当您向CMD提供program arg1 arg2 >out 2>err <in
之类的命令时,CMD会设置这些重定向,然后只使用program
调用arg1 arg2
,而不是>out
在Unix上,shell执行相同的操作 - 可以选择多个shell,但是它们都像这样处理重定向。类似地,管道由CMD或shell设置,而不是由在那些管道中运行的任何一个或所有程序设置。
因此,在Windows上,执行此操作的方法是运行CMD并让它执行重定向:
Process p = new ProcessBuilder ("cmd", "/c", "program arg1 arg2 >NUL 2>&1").start();
// this uses CMD's default parsing for args, so they must not contain space
// unless you insert 'data' quotes, or things that look like a substitutable %var%
或(假设Java7 +)告诉ProcessBuilder
进行重定向:
pb.redirectOutput (new File("NUL")).redirectErrorStream(true)