0

I searched a lot but did not find the solution. My goal is using java to call commands and get output in windows and linux. I found Runtime.exec method and did some experiments. Everything went ok except when there's space in the command parameters. Test code as below, also in github.
The code works well on windows, but in linux, output is empty:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
public static void main(String[] args) {
    try {
        Runtime rt = Runtime.getRuntime();
        String[] commandArray;
        if (isWindows()) {
            commandArray = new String[]{"cmd", "/c", "dir", "\"C:\\Program Files\""};
        } else {
            commandArray = new String[]{"ls", "\"/root/a directory with space\""};
        }
        String cmd = String.join(" ",commandArray);
        System.out.println(cmd);

        Process process = rt.exec(commandArray);
        BufferedReader input = new BufferedReader(
                new InputStreamReader(process.getInputStream()));
        String result = "";
        String line = null;
        while ((line = input.readLine()) != null) {
            result += line;
        }
        process.waitFor();
        System.out.println(result);

    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

public static boolean isWindows() {
    String OS = System.getProperty("os.name").toLowerCase();
    return (OS.indexOf("win") >= 0);
    }
}

if I execute the printed command in bash directly, then the output is as expected.

[root@localhost javatest]# javac Main.java 
[root@localhost javatest]# java Main
ls "/root/a directory with space"

[root@localhost javatest]# ls "/root/a directory with space"
a.txt  b.txt
[root@localhost javatest]# 

Can anyone explain why and give ways to solve?

1 Answer 1

2

There are two versions of exec.

  • exec(String command)

    Here you specify a command in a similar way to how you would do it on the command-line, i.e. you need to quote arguments with spaces.

    cmd /c dir "C:\Program Files"
    
  • exec(String[] cmdarray)

    Here you specify the arguments separately, so the arguments are given as-is, i.e. without quotes. The exec method will take care of any spaces and quote-characters in the argument, correctly quoting and escaping the argument as needed to execute the command.

    cmd
    /c
    dir
    C:\Program Files
    

So, remove the extra quotes you added:

if (isWindows()) {
    commandArray = new String[] { "cmd", "/c", "dir", "C:\\Program Files"};
} else {
    commandArray = new String[] { "ls", "/root/a directory with space"};
}
Sign up to request clarification or add additional context in comments.

3 Comments

thanks. can you help me with my real senario? curl -H "user-agent:some version that is required by server that has space". I tried omitting quotes but still failed. why?
@LeiYang Don't know. You should ask that as a new question, showing all the relevant information. --- Do note that -H and user-agent:blah blah are 2 arguments, not one.
I forgot to say it is curl. which maybe you're familiar with.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.