【问题标题】:Adding double quotes symbol in ProcessBuilder在 ProcessBuilder 中添加双引号符号
【发布时间】:2017-07-23 00:10:12
【问题描述】:

我正在使用ProcessBuilder来构建我的命令。我想在这篇文章之后构建我的命令:How do I launch a java process that has the standard bash shell environment?

也就是说,我的命令是这样的: /bin/bash -l -c "my program"

但是,我很难将双引号传递给ProcessBuilder,因为如果我将双引号本身添加到List<String> commandnew ProcessBuilder(List<String> command) 无法表达命令。 ProcessBuilder 将双引号识别为参数。

相关代码:

    //Construct the argument
    csi.add("/bin/bash");
    csi.add("-l");
    csi.add("-c");
    csi.add("\"");
    csi.add(csi_path);
    csi.add(pre_hash);
    csi.add(post_hash);
    csi.add("\"");

    String csi_output = Command.runCommand(project_directory, csi);

 public static String runCommand(String directory, List<String> command) {


    ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File(directory));
    Process process;
    String output = null;
    try {
        process = processBuilder.start();

        //Pause the current thread until the process is done
        process.waitFor();

        //When the process does not exit properly
        if (process.exitValue() != 0) {

            //Error
            System.out.println("command exited in error: " + process.exitValue());

            //Handle the error
            return readOutput(process);
        }else {

            output = readOutput(process);
            System.out.println(output);
        }

    } catch (InterruptedException e) {
        System.out.println("Something wrong with command: " +e.getMessage());

    } catch (IOException e) {
        System.out.println("Something wrong with command: " +e.getMessage());
    }

    return output;
}

Ps:我确实想使用ProcessBuilder 而不是Runtime.getRuntime.exec(),因为我需要在特定目录中运行命令。我需要使用ProcessBuilder.directory()

Ps:该命令运行后会以2退出。系统似乎可以识别此命令。奇怪的是用2退出后没有输出。

Ps:预期的命令是/bin/bash -l -c "/Users/ryouyasachi/GettyGradle/build/idea-sandbox/plugins/Getty/classes/python/csi 19f4281 a562db1"。我打印了这个值,它是正确的。

【问题讨论】:

  • 您不需要这样做。 List 中的每个元素都将作为单独的参数传递给命令,因此只需将 List&lt;String&gt; 传递给 ProcessBuilder
  • 在我看来,这意味着将 new ProcessBuilder(sb.toString()) 更改为 new ProcessBuilder(command)
  • 请记住,在命令行中使用"..." 的原因是为了否定空格,因此引号之间的所有内容都作为单个参数传递给进程
  • @MadProgrammer 我试过你的方法,但命令仍然以 2 退出。似乎问题在于添加 /bin/bash -l -c,因为没有它my program 运行正常。
  • @JiaxiangLiang 用您最近尝试的内容更新您的帖子。

标签: java bash shell


【解决方案1】:

解决问题的最佳方法是先构造命令并将其传递给列表。所以,与其做这一切。

csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");

你应该先构造命令

StringBuilder sb = new StringBuilder();
sb.append("/bin/bash -l -c");
sb.append("\""+csi_path+pre_hash+post_hash+"\"");// add whitespace between the varaible, if required.
System.outprintln(sb.toString());  //verify your command here

csi.add(sb.toString());

另外,验证以上所有变量值。

【讨论】:

  • 我试过你的方法。它似乎无法识别“/bin/bash -l -c”。输出为Cannot run program "/bin/bash -l -c" (in directory "/Users/ryouyasachi/Getty/semantiful-differentials-getty/getty/dsproj"): error=2, No such file or directory
  • 另外,我已经多次提到,请验证您的变量
  • 另外,请注意,使用 processbuilder,您将 pwd 更改为 /Users/ryouyasachi/Getty/semantiful-differentials-getty/get‌​ty/dsproj。因此,您需要尝试从那里执行/bin/bash -l -c 命令。如果没有执行,那不是你的 java 代码问题。
  • 您需要拿出实际命令并先手动尝试,然后需要在java代码中进行模拟。不要以相反的顺序执行,否则您将始终面临此问题
  • 我可以从我的终端运行它。变量也很好,我仔细检查了它。
【解决方案2】:

感谢@Ravi 的想法!

    //Construct the argument
    csi.add("/bin/bash");
    csi.add("-l");
    csi.add("-c");
    csi.add("\"" + csi_path + " " + pre_hash+ " " + post_hash + "\"");


    String csi_output = Command.runCommand(project_directory, csi);

Process 必须分别获取每个参数才能识别命令。棘手的部分是,在我想要的命令中 /bin/bash -l -c "/mypath/csi"

"/mypath/csi" 需要被Process 视为一个单独的参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 2018-03-24
    • 2012-08-20
    相关资源
    最近更新 更多