Jiaxiang Liang
Jiaxiang Liang

Reputation: 17

Adding double quotes symbol in ProcessBuilder

I am using ProcessBuilderto build my command. I want to build my command following this post:How do I launch a java process that has the standard bash shell environment?

Namely, my command is something like this: /bin/bash -l -c "my program"

However, I am having difficulties to pass the double quotes into ProcessBuilder, as new ProcessBuilder(List<String> command) failed to phrase the command if I natively add double quotes to List<String> command. ProcessBuilder recognizes the double quotes as an argument.

Relevant code:

    //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: I do want to use ProcessBuilder instead of Runtime.getRuntime.exec() because I need to run the command in a specific directory. I need to use ProcessBuilder.directory().

Ps: The command will exit with 2 after running. It seems that the system can recognize this command. The strange thing is that it has no output after exiting with 2.

Ps: The expected command is /bin/bash -l -c "/Users/ryouyasachi/GettyGradle/build/idea-sandbox/plugins/Getty/classes/python/csi 19f4281 a562db1". I printed the value and it was correct.

Upvotes: 0

Views: 1490

Answers (2)

Jiaxiang Liang
Jiaxiang Liang

Reputation: 17

Thx for @Ravi 's idea!

    //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);

The Process has to take each argument separately in order to recognize the command. The tricky part is that, in my desired command /bin/bash -l -c "/mypath/csi"

"/mypath/csi" needs to be viewed as one single argument by Process.

Upvotes: 0

Ravi
Ravi

Reputation: 31417

Best way to troubleshoot your problem is to construct the command first and pass it to the list. So, instead of doing all this.

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("\"");

You should first construct the command

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());

Also, verify all above variable values.

Upvotes: 1

Related Questions