Java, Runtime.exec или ProcessBuilder: как чтобы узнать, является ли файл оболочкой или двоичным?

Я ищу наиболее эффективный способ решить:

  • Должен ли я предварительно предварять предоставленную пользователем командную строку с исполняемый файл оболочки
  • Если да, то что это за исполняемый файл? (/ bin / sh? / usr / bin / perl? / usr / bin / ksh? c: /../ cmd.exe?)

Это известно, что для запуска сценария оболочки из Java вместо этого следует запустить оболочку:

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "script.sh", "arg1", "arg2);

Чтобы запустить двоичный файл, следует запустить сам двоичный файл:

ProcessBuilder pb = new ProcessBuilder("/path/binary", "arg1", "arg2);

Если двоичный файл выполняется с оболочкой, он выдает ошибку:

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2);
(sh: cannot execute binary file)

Если сценарий оболочки выполняется без двоичного файла оболочки, возникает ошибка:

ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2);
(error 2: file not found)

Я в ситуации, когда мое приложение не знает, что оно запускает, двоичный файл или сценарий.

Запущенное приложение является обработчиком событий предоставлено конечным пользователем . Скорее всего, это сценарий оболочки, выполняемый под Unix; но это может быть * .cmd под Windows или сценарий Perl, выполняемый на какой-то малоизвестной платформе. В конце концов, это Java .

Моей первой наивной попыткой было запустить командную строку с оболочкой и посмотреть если он работает.Если нет, попробуйте выполнить его как двоичный файл.

Это уродливо и рискованно: при какой-то неизвестной комбинации платформы и оболочки второй запуск все еще может выполнить сценарий во второй раз с непредсказуемыми результатами.

Кроме того, я не могу сказать, когда скрипт запустился нормально и потерпел неудачу из-за некоторой собственной проблемы, когда я просто не могу его запустить.

Лучшее, что я сейчас рассматриваю, это:

  • Прочтите сценарий и найдите все непечатаемые байты.
  • Если обнаружите, считайте его двоичным.
  • Если нет, добавьте / bin / sh (или cmd. exe, если под Windows)

Сообщите, если у вас есть идеи получше.

ОБНОВЛЕНИЕ / ЧАСТИЧНОЕ РЕШЕНИЕ

Спасибо всем, кто поделился со мной своими мыслями.

Оказывается, я запутал себя и остальную часть Интернета :)

Не требуется добавлять двоичный файл должен перед вводимой пользователем командной строкой, при условии, что:

  1. сценарий находится в PATH
  2. ] (для Unix) сценарий является исполняемым
  3. (для Unix) сценарий имеет #! / path / to / интерпретатор

Пока я тестировал свой код, то или иное из этих условий не соблюдалось. : - (

После тщательного выполнения теста с нуля был выполнен скрипт.

Пункт 3 может быть выполнен только пользователем и должен быть задокументирован в Руководстве пользователя.

Из-за способа, которым они сценарии распространяются на целевую систему, они могут быть не исполняемыми и могут не входить в PATH.

Единственный путь, который меня волнует, является относительным, поэтому достаточно добавить ./ к любому относительному пути.

Сделать скрипты исполняемыми под Unix (и любой другой платформой) - более сложная задача.Размещение / bin / sh перед ним может помочь, но, насколько я помню, в Solaris оболочка не будет выполнять неисполняемый сценарий.

Позже на этой неделе я опубликую еще одно обновление.

11
задан Не морозь меня 10 January 2012 в 03:03
поделиться