2015-04-15 3 views
2

У меня есть приложение, которое я пытаюсь выполнить через вызов Runtime.exec().Runtime exec с аргументами, содержащими пробелы

Поскольку некоторые аргументы имеют пробелы, как я могу правильно избежать аргументов, чтобы он работал как в Linux, так и в Windows? Я знаю, что в Windows вы обычно используете двойные кавычки вокруг строки с пробелами, а linux использует косую черту.

С пробелами я ожидаю, что программа, которую я запускаю (Windows xcopy сейчас), вернется почти сразу и указывает, что число параметров неверно. Но вызов waitFor() зависает.

String[] commandArray = new String[3]; 
commandArray[0] = applicationPath; 
commandArray[1] = someFileWhichMayHaveSpaces; 
commandArray[2] = anotherFileWhichMayHaveSpaces; 

Process appProcess = Runtime.getRuntime().exec(commandArray); 
int returnCode = appProcess.waitFor(); 
+1

Я не думаю, что вам нужно избегать аргументов при использовании Runtime.exec(). Параметры должны передаваться непосредственно в целевое приложение без каких-либо изменений. – Richard

+2

Переключиться на 'ProcessBuilder' –

+0

Переключение на ProcessBuilder с тем же списком args не влияет. –

ответ

3

У меня была идентичная проблема с приложением, которое я разрабатывал несколько недель назад. В конечном счете, я отказался от использования raw Runtime.exec() (pitfalls of Runtime.exec()) и решил использовать библиотеку Apache Commons Exec. Это помогло решить различные проблемы из коробки и случайные зависания во время исполнения. Его метод addArguments() принимает параметр handleQuoting, поэтому я создал простой метод util, который проверяет ОС, и я запрашиваю обработку цитирования для Windows, тогда как для Linux я передаю false. Если вам нужны некоторые рабочие примеры, на веб-сайте библиотеки есть несколько учебников. Вы также можете взглянуть на мой класс, который использует commons-exec в проекте Open LaTeX Studio.

0

Похоже, что нет никаких проблем с пробелами в args, по крайней мере, в среде Windows. Проблема заключалась в том, что xcopy запрашивал/останавливал ответ на вопрос, если источником копии был файл или каталог. Я предположил, что это задыхается от пространств, но, видимо, это не так. Я смог использовать код, который у меня есть в вопросе как есть, и не должен был использовать ProcessBuilder.

0

В Windows, если у вас есть сомнения, вы должны использовать одну из перегрузок Runtime.exec, которая в качестве аргумента командной строки берет строку, а не строковый массив. Это позволяет вам самостоятельно построить строку командной строки для нового процесса, чтобы вы могли убедиться в правильности синтаксиса.

Если вы используете метод массива, Java должен преобразовать массив в одну строку. Это будет сделано с использованием стандартного алгоритма, который предполагает, что целевой процесс использует синтаксический анализатор командной строки Microsoft C (или совместимый). Это будет обычно ОК, но не всегда.

Смежные вопросы