问题描述
我正在尝试从java代码执行外部命令,但是我注意到 Runtime.getRuntime()。exec(...)
之间存在差异。和 new Process(...)。start()
。
I'm trying to execute an external command from java code, but there's a difference I've noticed between Runtime.getRuntime().exec(...)
and new Process(...).start()
.
使用运行时
:
Process p = Runtime.getRuntime().exec(installation_path +
uninstall_path +
uninstall_command +
uninstall_arguments);
p.waitFor();
exitValue为0且命令终止确定。
the exitValue is 0 and the command is terminated ok.
然而,使用 ProcessBuilder
:
Process p = (new ProcessBuilder(installation_path +
uninstall_path +
uninstall_command,
uninstall_arguments)).start();
p.waitFor();
退出值为1001,命令终止于中间,但 waitFor
返回。
the exit value is 1001 and the command terminates in the middle, although waitFor
returns.
我应该如何解决 ProcessBuilder
?
推荐答案
的各种重载Runtime.getRuntime()。exec(...)
取一个字符串数组或一个字符串。 exec()
的单字符串重载将字符串标记为参数数组,然后将字符串数组传递给 exec()之一
带有字符串数组的重载。另一方面, ProcessBuilder
构造函数只接受字符串的varargs数组或字符串的 List
。假定数组或列表中的字符串是单个参数。无论哪种方式,获得的参数然后连接到一个字符串,传递给操作系统执行。
The various overloads of Runtime.getRuntime().exec(...)
take either an array of strings or a single string. The single-string overloads of exec()
will tokenise the string into an array of arguments, before passing the string array onto one of the exec()
overloads that takes a string array. The ProcessBuilder
constructors, on the other hand, only take a varargs array of strings or a List
of strings, where each string in the array or list is assumed to be an individual argument. Either way, the arguments obtained are then joined up into a string that is passed to the OS to execute.
所以,例如,在Windows上,
So, for example, on Windows,
Runtime.getRuntime().exec("C:\DoStuff.exe -arg1 -arg2");
将运行 DoStuff.exe
程序两个给出的论点。在这种情况下,命令行会被标记化并重新组合在一起。但是,
will run a DoStuff.exe
program with the two given arguments. In this case, the command-line gets tokenised and put back together. However,
ProcessBuilder b = new ProcessBuilder("C:\DoStuff.exe -arg1 -arg2");
将失败,除非碰巧有一个名称为 DoStuff的程序。 exe -arg1 -arg2
在 C:\
中。这是因为没有标记化:假定运行的命令已被标记化。相反,你应该使用
will fail, unless there happens to be a program whose name is DoStuff.exe -arg1 -arg2
in C:\
. This is because there's no tokenisation: the command to run is assumed to have already been tokenised. Instead, you should use
ProcessBuilder b = new ProcessBuilder("C:\DoStuff.exe", "-arg1", "-arg2");
或者
List<String> params = java.util.Arrays.asList("C:\DoStuff.exe", "-arg1", "-arg2");
ProcessBuilder b = new ProcessBuilder(params);
这篇关于ProcessBuilder和Runtime.exec之间的区别()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!