Рубрики
Без рубрики

Как запустить команду оболочки в Java

Краткое руководство по двум способам выполнения команды оболочки в Java, как в Windows, так и в UNIX.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы проиллюстрируем два способа выполнения команды оболочки из Java кода .

Первый-использовать класс Runtime и вызвать его метод exec .

Вторым и более настраиваемым способом будет создание и использование экземпляра ProcessBuilder .

2. Зависимость от операционной системы

Прежде чем мы создадим новый Процесс , выполняющий нашу команду оболочки, нам нужно сначала определить операционную систему, в которой работает наша JVM .

Это потому, что в Windows нам нужно запустить вашу команду в качестве аргумента для cmd.exe shell и на всех других операционных системах мы можем выпустить стандартную оболочку, называемую sh:

boolean isWindows = System.getProperty("os.name")
  .toLowerCase().startsWith("windows");

3. Вход и выход

Кроме того, нам нужен способ подключения к входным и выходным потокам нашего процесса.

По крайней мере вывод должен быть потреблен – в противном случае наш процесс не вернется успешно, вместо этого он зависнет.

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

private static class StreamGobbler implements Runnable {
    private InputStream inputStream;
    private Consumer consumer;

    public StreamGobbler(InputStream inputStream, Consumer consumer) {
        this.inputStream = inputStream;
        this.consumer = consumer;
    }

    @Override
    public void run() {
        new BufferedReader(new InputStreamReader(inputStream)).lines()
          .forEach(consumer);
    }
}

ПРИМЕЧАНИЕ: Этот класс реализует интерфейс Runnable , что означает, что он может быть выполнен любым Исполнителем .

4. Runtime.exec()

Вызов метода Runtime.exec () -это простой, еще не настраиваемый способ создания нового подпроцесса.

В следующем примере мы запросим список каталогов домашнего каталога пользователя и распечатаем его на консоли:

String homeDirectory = System.getProperty("user.home");
Process process;
if (isWindows) {
    process = Runtime.getRuntime()
      .exec(String.format("cmd.exe /c dir %s", homeDirectory));
} else {
    process = Runtime.getRuntime()
      .exec(String.format("sh -c ls %s", homeDirectory));
}
StreamGobbler streamGobbler = 
  new StreamGobbler(process.getInputStream(), System.out::println);
Executors.newSingleThreadExecutor().submit(streamGobbler);
int exitCode = process.waitFor();
assert exitCode == 0;

5. ProcessBuilder

Для второй реализации нашей вычислительной задачи мы будем использовать ProcessBuilder . Это предпочтительнее, чем подход Runtime , потому что мы можем настроить некоторые детали.

Например, мы можем:

  • измените рабочий каталог, в котором выполняется команда оболочки, с помощью builder.directory()
  • настройка пользовательской карты ключ-значение в качестве среды с помощью builder.environment()
  • перенаправление потоков ввода и вывода на пользовательские замены
  • унаследуйте их оба в потоках текущего JVM процесса с помощью builder.inherited()
ProcessBuilder builder = new ProcessBuilder();
if (isWindows) {
    builder.command("cmd.exe", "/c", "dir");
} else {
    builder.command("sh", "-c", "ls");
}
builder.directory(new File(System.getProperty("user.home")));
Process process = builder.start();
StreamGobbler streamGobbler = 
  new StreamGobbler(process.getInputStream(), System.out::println);
Executors.newSingleThreadExecutor().submit(streamGobbler);
int exitCode = process.waitFor();
assert exitCode == 0;

6. Заключение

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

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

Как всегда, вы найдете источники на GitHub .