Как заставить ProcessBuilder обрабатывать вложенные кавычки?

У меня возникают проблемы с получением ProcessBuilder выполнения командной строки так же, как консоль cmd.exe.

  1. Командная строка: show_parameters.bat jdk-1
    Console tokens:
    
    jdk-1_5_0_22-windows-i586-p.exe
    /s
    /v"/qn INSTALLDIR=\"C:\Program
    Files
    (x86)\gili\""
    
    0_22-windows-i586-p.exe /s /v"/qn INSTALLDIR=\"C:\Program Files (x86)\gili\""
  2. Пакетный файл show_parameters.bat (ниже) показывает токены, на которые cmd.exe разбивает командную строку.
  3. Testcase.java (ниже) пытается выполнить ту же командную строку, что и №1, используя ProcessBuilder.
  4. Если вы запустите show_parameters.bat jdk-1

    Console tokens:
    
    jdk-1_5_0_22-windows-i586-p.exe
    /s
    /v"/qn INSTALLDIR=\"C:\Program
    Files
    (x86)\gili\""
    
    0_22-windows-i586-p.exe /s /v"/qn INSTALLDIR=\"C:\Program Files (x86)\gili\"", вы получите:

    Console tokens:
    
    jdk-1_5_0_22-windows-i586-p.exe
    /s
    /v"/qn INSTALLDIR=\"C:\Program
    Files
    (x86)\gili\""
    
  5. Если вы запустите java Testcase, вы получите:

    Java tokens: [cmd.exe, /c, show_parameters.bat, jdk-1_5_0_22-windows-i586-p.exe,
     /s, /v"/qn INSTALLDIR=\"C:\Program Files (x86)\gili\""]
    
    Console tokens:
    
    jdk-1_5_0_22-windows-i586-p.exe
    /s
    "/v"/qn
    INSTALLDIR
    \"C:\Program Files (x86)\gili\"
    ""
    

Можно ли заставить ProcessBuilder производить ту же токенизацию, что и в #1? Или это ошибка в Java?


show_parameters.bat

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

    echo.
    echo Console tokens:
    echo.

    :again
    if [%1] == [] goto end
      echo %1
      shift
      goto again
    :end

Тесткейс.java

import java.io.*;

public class Testcase
{

    public static void main(String[] args) throws IOException, InterruptedException
    {
        String base = "C:\\Program Files (x86)\\gili";
        ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "show_parameters.bat", "jdk-1_5_0_22-windows-i586-p.exe", "/s",
                "/v\"/qn INSTALLDIR=\\\"" + base + "\\\"\"");
        processBuilder.redirectErrorStream(true);
        System.out.println("Java tokens: " + processBuilder.command());
        Process process = processBuilder.start();
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        while (true)
        {
            String line = in.readLine();
            if (line == null)
                break;
            System.out.println(line);
        }
    }
}

person Gili    schedule 17.09.2013    source источник


Ответы (1)


Попробуйте так:

ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "show_parameters.bat jdk-1_5_0_22-windows-i586-p.exe /s /v\"/qn INSTALLDIR=\\\"" + base + "\\\"\"");

or

ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "show_parameters.bat jdk-1_5_0_22-windows-i586-p.exe /s /v\"/qn INSTALLDIR='" + base + "'\"");

"/c" ожидает только один аргумент - команду, которая будет выполнена в CMD

person stan    schedule 17.09.2013
comment
Вот это да. Я не могу поверить, что это была проблема! Спасибо за зоркий глаз! - person Gili; 17.09.2013