【问题标题】:Passing pre-escaped command-line arguments to ProcessBuilder将预先转义的命令行参数传递给 ProcessBuilder
【发布时间】:2013-10-23 08:58:53
【问题描述】:

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

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++ 文件,但是在检查g++ 的stderr 之后,我发现发生了以下错误:

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[]?

【问题讨论】:

    标签: java command-line


    【解决方案1】:

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

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

    简单。

    【讨论】:

      【解决方案2】:

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

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

      (发布的内容不足以获得足够的代表点数,无法将其作为正常评论。)

      【讨论】:

        猜你喜欢
        • 2011-04-15
        • 2015-02-08
        • 2015-06-09
        • 2017-10-22
        • 2019-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多