Search code examples
javacmdprocessbuilder

Escaping illegal characters in params


I execute an external batch file from Java and pass a special attribute to it. I've found that several characters are passed incorrectly to my batch file. I couldn't find any limitations mentioned in ProcessBuilder class nor method of escaping those chars.

public static void main(String[] args) throws IOException {
    /*
     * correct processing: almost everything (even #$*%:'\/~?)
     * fatal error:        |<>
     * trimming:           ;=&
     */
    ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "batch.bat", "a;b;c;d");
    final Process process = builder.start();
    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    String line;
    while ((line = br.readLine()) != null) {
       System.out.println(line);
    }
    System.out.println("Program terminated!");
}

My batch file is just

echo %1

The code above prints only the first character before the semi-colon (a).

I run this on Win7 and JDK 7 64-bit.

Curently I replacing all these characters with rare ones and the reverse replacement is done later in my final script.

Any idea how to pass these characters correctly without any 'translation'?


Solution

  • Microsoft Support Site stated that

    When a semicolon (;) or equal sign (=) is used as a command line argument in a batch file, it is treated as a blank space.

    cmd /? stated that

    The special characters that require quotes are:
         <space>
         &()[]{}^=;!'+,`~
    

    So just use

    batch.bat "a;b;c;d"
    

    That is

    new ProcessBuilder("cmd", "/c", "batch.bat", "\"a;b;c;d\"");
    

    Later I spotted the output is

    "a;b;c;d"
    Program terminated!
    

    Where the extra " may not be what you want. Use %~1 to strip it off. That is, change your bat file to:

    echo %~1