Вопрос по java – Является ли платформа Java Runtime.exec (String []) независимой?

3

У меня был код, который запускал команды черезRuntime.getRuntime.exec(String)и это работало на Windows. Когда я переместил код в Linux, он сломался, и единственным способом исправить это было переключиться наexec(String[]) версия. Если я оставлю все так, будет ли код работать одинаково в Windows и Linux, или я должен использовать exec (String) в Windows и exec (String []) в Linux?

Ваш Ответ

7   ответов
4

String[] на обоих.

Ответ ядал вам раньше был результатом нескольких жалких часов отладки производственного программного обеспечения, работающего на Windows.

После долгих усилий мы (I) пришли к решению, опубликованному ранее (используйтеString[] )

Поскольку проблемы, с которыми вы столкнулись, были в Linux, я думаю, массива на обоих будет лучшим.

КСТАТИ. Я попробовал этот метод с Java 1.4, с тех пор доступен новый класс:ProcessBuilder добавлено на Java1.5. Я не уверен, что это такое, но для этого должна быть веская причина. Взгляните на него и прочитайте, в чем разница между этим Runtime.exec. Вероятно, это будет лучший вариант.

Наконец, некоторые команды не будут работать на любой платформе, потому что они встроены в оболочку (либо Windows cmd, либо bash / sh / etc), напримерdir или жеecho и некоторые из них. Поэтому я бы рекомендовал сделать дополнительный / дополнительный тест на каждой целевой платформе и добавить обработчики исключений для неподдерживаемых команд.

:)

Это работало на обеих операционных системах. Благодарю. Geo
2

g [] просто разделяет их по пробелу. Он не интерпретирует кавычки так, как это делает введенная вручную команда оболочки, поэтому вам следует вызвать версию String []. Но если вы используете Sun JDK на обеих платформах, поведение должно быть одинаковым.

Однако, поскольку Windows предоставляет другие команды оболочки, как и другие операционные системы (например, copy вместо cp), ваши команды могут работать не на всех платформах.

2

какую нетривиальную команду вы можете передать exec () и ожидать получения разумных результатов как в Windows, так и в Linux? На вопрос, является ли exec () платформо-независимым видом, по-видимому, упускается весь смысл exec (), который заключается в вызове поведения, специфичного для платформы.

Чтобы ответить на ваш вопрос, да - способ интерпретации командной строки будет разным на разных платформах (и, возможно, для разных оболочек в Linux), и использование версии String [] с большей вероятностью приведет к параметрам проходить правильно.

Я пытался выполнить javac для всех файлов .java внутри проекта, а также включить jar-зависимости. Geo
@Отметка. Не так много на самом деле. Аргументы с обеих сторон различны, как путь / и разделитель пути: vs; Приводы и т. Д., Поэтому команды не будут прозрачно перемещаться с одной платформы на другую.
@Geo: существует начиная с Java 1.6, я думаю, API для компилятора Java. Я думаю, что-то вроде java.lang.Compiler, он был добавлен именно для того, чтобы избежать подобных проблем и позволить контейнерам, таким как контейнеры сервлетов, компилировать сгенерированный файл .java из приложения, а не из внешнего процесса.
Ах, я должен был догадаться - запускать команды JDK - разумная вещь, которую нужно делать из Java-приложения.
2

который принимает одну строку, и тем, который принимает массив, состоит в том, что версия массива позволяет вам указать, как нужно разбивать команду и ее аргументы (то есть правильно). Когда вы используете метод (ы), которые принимают только строку, метод разбивает ее на массив в пробелах. Обработка с тех пор обрабатывается одинаково для обоих методов.

Это код из класса Runtime, который показывает, как он разбивает одну строку на массив, а затем вызывает версию String [] для продолжения обработки.

   public Process exec(String command, String[] envp, File dir)
            throws IOException {
         if (command.length() == 0)
             throw new IllegalArgumentException("Empty command");

         StringTokenizer st = new StringTokenizer(command);
         String[] cmdarray = new String[st.countTokens()];
         for (int i = 0; st.hasMoreTokens(); i++)
             cmdarray[i] = st.nextToken();
         return exec(cmdarray, envp, dir);
     }

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

1

This method checks that cmdarray is a valid operating system command. Which commands are valid is system-dependent, but at the very least the command must be a non-empty list of non-null strings.

Так что да, это зависит от системы. Кстати, не могли бы вы опубликовать соответствующий код, чтобы мы могли видеть, что вы (в конце концов) делаете неправильно?

[1]: http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec (java.lang.String [], java.lang.String [], java.io.File)

Хорошо, в превью ссылка не битая!
1

Команды, разработанные для Windows, не будут работать в Linux и должны быть переписаны.

1

вы можете узнать, какая ОС работает, используя что-то вроде следующего:

        String os = System.getProperty("os.name").toLowerCase();
        if (os.indexOf("win") >= 0) {
            // Windows Commands
        } else {
            // Linux Commands
        }

Другим хорошим вариантом было бы написать свои команды в сценарии (.bat для Windows и .sh для Linux) и вместо этого вызывать эти сценарии.

Похожие вопросы