Java Runtime Exec With White Spaces On Path Name

2019-03-04 04:28发布

I'm trying to run a OSX command which is plutil to convert certain plist to json format. The command that I use in terminal is

 plutil -convert json -o - '/Users/chris/project/temp tutoral/project.plist'

This command with path name having white spacing works fine in my terminal with the apostrophe (") sign covering the path name but the problem is with running this command in java's Runtime.getRuntime().exec(cmdStr) below is the code that i wrote

public static void main(String args[]){
        LinkedList<String> output = new LinkedList<String>();
        String cmdStr = "plutil -convert json -o - /Users/chris/project/temp tutoral/project.plist";
        //String cmdStr = " plutil -convert json -o - '/Users/chris/project/temp tutoral/project.plist'";
        //String [] cmdStr ={ "plutil -convert json -o - ", "\"Users/chris/project/temp tutoral/project.plist\""};

        Process p;
        try {
            p = Runtime.getRuntime().exec(cmdStr);
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = "";
            while ((line = reader.readLine()) != null) {
                output.add(line);
                System.out.println(line);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

If i run this code it would give me an error of

'Users/chris/project/temp: file does not exist or is not readable or is not a regular file (Error Domain=NSCocoaErrorDomain Code=260 "The file “temp” couldn’t be opened because there is no such file." UserInfo=0x7fd6b1c01510 {NSFilePath='Users/chris/project/temp, NSUnderlyingError=0x7fd6b1c01280 "The operation couldn’t be completed. No such file or directory"})
tutoral/project.plist': file does not exist or is not readable or is not a regular file (Error Domain=NSCocoaErrorDomain Code=260 "The file “project.plist” couldn’t be opened because there is no such file." UserInfo=0x7fd6b1d6dd00 {NSFilePath=tutoral/project.plist', NSUnderlyingError=0x7fd6b1d6c6b0 "The operation couldn’t be completed. No such file or directory"})

I have also tried,

  • putting in the apostrophe in the command string
  • changing the command in array string as suggested my few sites

but non of them worked.

Please advice if i did anything wrong in arranging my command or any syntax error that i made. Thanks in advance.

标签: java macos shell
2条回答
一纸荒年 Trace。
2楼-- · 2019-03-04 04:42

Try this

/Users/chris/project/temp\ tutoral/project.plist

EDIT: I misplaced the backlash on my first post

查看更多
看我几分像从前
3楼-- · 2019-03-04 05:02

The call Runtime.getRuntime().exec(cmdStr) is a convenience method - a shortcut for calling the command with an array. It splits the command string on white spaces, and then runs the command with the resulting array.

So if you give it a string in which any of the parameters includes spaces, it does not parse quotes like the shell does, but just breaks it into parts like this:

// Bad array created by automatic tokenization of command string
String[] cmdArr = { "plutil",
                    "-convert",
                    "json",
                    "-o",
                    "-",
                    "'/Users/chris/project/temp",
                    "tutoral/project.plist'" };

Of course, this is not what you want. So in cases like this, you should break the command into your own array. Each parameter should have its own element in the array, and you don't need extra quoting for the space-containing parameters:

// Correct array 
String[] cmdArr = { "plutil",
                    "-convert",
                    "json",
                    "-o",
                    "-",
                    "/Users/chris/project/temp tutoral/project.plist" };

Note that the preferred way to start a process is to use ProcessBuilder, e.g.:

p = new ProcessBuilder("plutil",
                       "-convert",
                       "json",
                       "-o",
                       "-",
                       "/Users/chris/project/temp tutoral/project.plist")
       .start();

ProcessBuilder offers more possibilities, and using Runtime.exec is discouraged.

查看更多
登录 后发表回答