So führen Sie einen Shell-Befehl in Java aus

1. Übersicht

In diesem Tutorial werden die beiden Möglichkeiten zum Ausführen eines Shell-Befehls aus Java- Code heraus veranschaulicht .

Die erste besteht darin, die Runtime- Klasse zu verwenden und ihre exec- Methode aufzurufen .

Die zweite und anpassbarere Möglichkeit besteht darin, eine ProcessBuilder- Instanz zu erstellen und zu verwenden .

2. Betriebssystemabhängigkeit

Bevor wir einen neuen Prozess erstellen , der unseren Shell-Befehl ausführt, müssen wir zuerst das Betriebssystem ermitteln, auf dem unsere JVM ausgeführt wird.

Das liegt daran, dass wir unter Windows unseren Befehl als Argument für die Shell cmd.exe ausführen müssen und unter allen anderen Betriebssystemen eine Standard-Shell namens sh ausgeben können :

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

3. Ein- und Ausgabe

AußerdemWir brauchen eine Möglichkeit, uns in die Eingabe- und Ausgabeströme unseres Prozesses einzubinden.

Zumindest muss die Ausgabe verbraucht werden - andernfalls kehrt unser Prozess nicht erfolgreich zurück, sondern bleibt hängen.

Implementieren wir eine häufig verwendete Klasse namens StreamGobbler, die einen InputStream verwendet :

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); } }

ANMERKUNG: Diese Klasse implementiert die Runnable- Schnittstelle, was bedeutet, dass sie von jedem Executor ausgeführt werden kann .

4. Runtime.exec ()

Ein Methodenaufruf von Runtime.exec () ist eine einfache, noch nicht anpassbare Möglichkeit, einen neuen Unterprozess zu erzeugen .

Im folgenden Beispiel fordern wir eine Verzeichnisliste des Home-Verzeichnisses eines Benutzers an und drucken sie auf der Konsole aus:

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

Für die zweite Implementierung unseres Computerproblems verwenden wir einen ProcessBuilder . Dies wird dem Runtime- Ansatz vorgezogen, da wir einige Details anpassen können.

Zum Beispiel können wir:

  • Ändern Sie das Arbeitsverzeichnis, in dem unser Shell-Befehl ausgeführt wird, mit builder.directory ()
  • Richten Sie mit builder.environment () eine benutzerdefinierte Schlüsselwertzuordnung als Umgebung ein.
  • Leiten Sie Eingabe- und Ausgabestreams zu benutzerdefinierten Ersetzungen um
  • Erben Sie beide mit builder.inheritIO () an die Streams des aktuellen JVM- Prozesses.
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. Fazit

Wie wir in diesem kurzen Tutorial gesehen haben, können wir einen Shell-Befehl in Java auf zwei verschiedene Arten ausführen .

Wenn Sie die Ausführung des erzeugten Prozesses anpassen möchten, z. B. um sein Arbeitsverzeichnis zu ändern, sollten Sie im Allgemeinen die Verwendung eines ProcessBuilder in Betracht ziehen .

Wie immer finden Sie die Quellen auf GitHub .