0

我今天在设置一组本地通信程序时遇到了这个问题。基本上,我的一个应用程序正在向另一个应用程序发送一些数据,而这些数据的一部分是一个包含要执行的命令的字符串(就像您从命令行执行的那样)。比方说,例如:

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正确地传递给构造函数。这些参数并不是那么简单,简单地将字符串拆分为 a' '也可以正常工作;参数可能包含用双引号转义的空格。例如:

g++ "..\my documents\foo.cpp" bar.cpp -o foobar

可能是来自应用程序的命令并将该字符串拆分' '并将其传递给ProcessBuilder将导致损坏的参数。

如果没有正确的方法来做到这一点,有人可以指点我一个独立的命令行参数解析器(在 Java 中),它可以将命令行字符串转换为有效的String[]

4

2 回答 2

2

好吧,我现在觉得很愚蠢,但我通过简单地恢复到过去的好来达到了我想要的结果Runtime.getRuntime().exec(...)。我会留下这个问题,以防有人像我一样愚蠢并发现它很有用。

String exampleCommand = "g++ foo.cc bar.cc -o foobar";
Runtime sys = Runtime.getRuntime();
sys.exec(exampleCommand);

简单的。

于 2013-10-23T09:08:23.380 回答
1

对 Runtime.getRuntime().exec(...) 解决方案的评论:

Runtime.getRuntime().exec(...) 不再好。在 OSX El Capitan 上执行的 java 中,“Runtime.getRuntime().exec(...)”包含一个错误,该错误有时会在 java 程序退出时关闭打开的进程。它在以前的 OSX 版本上运行良好。但是,ProcessBuilder 适用于所有 OSX 版本。

(还没有发布足够多的代表点来将其作为正常评论。)

于 2015-11-12T19:22:16.763 回答