Как да стартирам команда на Shell в Java

1. Общ преглед

С този урок ще илюстрираме двата начина за изпълнение на командата на черупката от Java кода .

Първият е да се използва класът Runtime и да се извика неговият exec метод.

Вторият и по-персонализиран начин ще бъде създаването и използването на екземпляр ProcessBuilder .

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

Преди да създадем нов процес, изпълняващ нашата командна команда, първо трябва да определим операционната система, на която работи нашата JVM .

Това е така, защото в Windows трябва да стартираме нашата команда като аргумент на обвивката cmd.exe и на всички други операционни системи можем да издадем стандартна обвивка, наречена 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 . Това се предпочита пред подхода по време на изпълнение , защото можем да персонализираме някои детайли.

Например можем да:

  • променете работната директория, в която се изпълнява командата на черупката, използвайки builder.directory ()
  • настройте персонализирана карта ключ-стойност като среда, използвайки builder.environment ()
  • пренасочване на входни и изходни потоци към персонализирани замествания
  • наследява и двамата в потоците на текущия JVM процес с помощта на builder.inheritIO ()
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 .