Java 将预先转义的命令行参数传递给ProcessBuilder

Java 将预先转义的命令行参数传递给ProcessBuilder,java,command-line,Java,Command Line,我今天在设置本地通信程序集时遇到了这个问题。基本上,我的一个应用程序正在向另一个应用程序发送一些数据,其中一部分数据是一个包含要执行的命令的字符串(就像您在命令行中所做的那样)。比如说: g++ foo.cc bar.cc -o foobar g++ "..\my documents\foo.cpp" bar.cpp -o foobar 是我的第一个应用程序发送的命令。接收命令的第二个应用程序(除其他外)需要在执行其他处理后执行此命令 现在,起初我认为使用ProcessBuilder,这将是

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

g++ foo.cc bar.cc -o foobar
g++ "..\my documents\foo.cpp" bar.cpp -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++
文件,但是在检查
g++
stderr
之后,我发现发生了以下错误:

g++.exe: error: foo.cc bar.cc -o foobar: No such file or directory
此时我意识到,
ProcessBuilder
类必须转义传递给它的所有参数,以准备命令行(因此它通常将参数作为单个参数的数组,而不仅仅是预定义的参数字符串)

我的问题是,“有没有办法将原始的参数字符串传递给ProcessBuilder,并在那里说,完全执行它?”

因为该命令来自另一个应用程序,并且绝不是静态的,所以我不能预先将参数分解成一个数组,并将它们正确地传递给
ProcessBuilder
构造函数。参数并不是那么简单,简单地将字符串围绕
'
拆分也可以正常工作;参数可能包含用双引号转义的空格。例如:

g++ foo.cc bar.cc -o foobar
g++ "..\my documents\foo.cpp" bar.cpp -o foobar
可能是来自应用程序的命令,将该字符串拆分为
'
并将其传递给
ProcessBuilder
将导致参数损坏


如果没有合适的方法可以做到这一点,请有人告诉我一个独立的命令行参数解析器(Java),它可以将命令行字符串转换为有效的
字符串[]

好吧,我现在觉得很傻,但我通过简单地返回到旧的
Runtime.getRuntime().exec(…)实现了我想要的结果
。我将把这个问题留给别人,以防有人像我这样愚蠢,觉得它有用

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

很简单。

好吧,我现在觉得很傻,但我通过简单地恢复到旧的
Runtime.getRuntime().exec(…)
实现了我想要的结果。我将把这个问题留给别人,以防有人像我这样愚蠢,觉得它有用

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

很简单。

好吧,我现在觉得很傻,但我通过简单地恢复到旧的
Runtime.getRuntime().exec(…)
实现了我想要的结果。我将把这个问题留给别人,以防有人像我这样愚蠢,觉得它有用

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

很简单。

好吧,我现在觉得很傻,但我通过简单地恢复到旧的
Runtime.getRuntime().exec(…)
实现了我想要的结果。我将把这个问题留给别人,以防有人像我这样愚蠢,觉得它有用

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

简单。

对Runtime.getRuntime()执行(…)解决方案的注释:

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


(没有发布足够的代表点,无法将其作为普通评论。)

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

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


(没有发布足够的代表点,无法将其作为普通评论。)

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

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


(没有发布足够的代表点,无法将其作为普通评论。)

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

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

(没有发布足够的评论,没有足够的代表点将此作为正常评论。)