我在设置本地通讯程序时遇到了这个问题。基本上我的一个应用程序是将一些数据发送到另一个,并且这些数据的一部分是一个包含要执行的命令的字符串(就像你从命令行那样)。比方说,例如:
g++ foo.cc bar.cc -o foobar
是我的第一个应用程序发送的命令。接收命令(以及其他内容)的第二个应用程序需要在执行其他处理后执行此命令。
现在,起初我认为使用ProcessBuilder
:
String exampleCommand = "g++ foo.cc bar.cc -o foobar";
ProcessBuilder builder = new ProcessBuilder(exampleCommand);
builder.start().waitFor();
然而,这是问题发生的地方。
CreateProcess error=2, The system cannot find the file specified
好吧,不用担心我想我不能把整个事情都抛到构建器中。命令的第一部分通常是一个简单的字符串,所以我想我可能会绕过第一个' '
分开程序名和参数。
String exampleCommand = "g++ foo.cc bar.cc -o foobar";
String[] parts = exampleCommand.split(" ", 2);
ProcessBuilder builder = new ProcessBuilder(parts[0], parts[1]);
builder.start().waitFor();
这让我离得更近了,现在可以正确找到g++
文件了,但是在检查stderr
g++
之后我发现发生了以下错误:
g++.exe: error: foo.cc bar.cc -o foobar: No such file or directory
此时我意识到ProcessBuilder
类必须转义传递给它的所有参数以准备命令行(因此它通常将参数作为单个参数的数组而不仅仅是预定义的参数字符串)。
我的问题是,“有没有办法将一个原始的参数字符串传递给ProcessBuilder并说出来,请执行这个?”
因为命令来自另一个应用程序并且绝不是静态的,所以我不能事先将参数分解为数组并正确地将它们传递给ProcessBuilder
构造函数。这些论点并不是那么简单,以至于简单地将字符串拆分为' '
也可以正常工作;参数可能包含使用双引号转义的空格。例如:
g++ "..\my documents\foo.cpp" bar.cpp -o foobar
可能是来自应用程序的命令,并将该字符串拆分为' '
并将其传递给ProcessBuilder
将导致参数损坏。
如果没有正确的方法可以请某人请指向一个独立的命令行参数解析器(在Java中),它可以将命令行字符串转换为有效的String[]
?
答案 0 :(得分:2)
好吧,我觉得现在很愚蠢但是我只是回到了原来的Runtime.getRuntime().exec(...)
,实现了我想要的结果。我会留下这个问题,万一有人和我一样傻,发现它很有用。
String exampleCommand = "g++ foo.cc bar.cc -o foobar";
Runtime sys = Runtime.getRuntime();
sys.exec(exampleCommand);
易。
答案 1 :(得分:1)
对Runtime.getRuntime()。exec(...)解决方案的评论:
Runtime.getRuntime()。exec(...)不再好了。在OSX El Capitan上执行的java中,'Runtime.getRuntime()。exec(...)'包含一个错误,有时在java程序退出时关闭打开的进程。它在以前的OSX版本上运行良好。但是,ProcessBuilder适用于所有OSX版本。
(还没有发布足够的重复点来将其作为正常评论。)