Hoe u een Shell-opdracht uitvoert in Java

1. Overzicht

Met deze tutorial illustreren we de twee manieren van het uitvoeren van een shell-commando van binnenuit Java code.

De eerste is om de Looptijd klasse en bel zijn exec methode.

De tweede en meer aanpasbare manier is om een ProcessBuilder voorbeeld.

2. Afhankelijkheid van besturingssysteem

Voordat we een nieuw Werkwijze bij het uitvoeren van onze shell-opdracht, moeten we eerst het besturingssysteem bepalen waarop onze JVM is aan het rennen.

Dat komt omdat, op ramen, we moeten onze opdracht uitvoeren als argument voor de cmd.exe shell en op alle andere besturingssystemen kunnen we een standaardshell uitgeven, genaamd sh:

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

3. Invoer en uitvoer

Verderwe hebben een manier nodig om aan te sluiten bij de input- en outputstromen van ons proces.

Minstens de output moet worden verbruikt - anders keert ons proces niet succesvol terug, maar zal het vastlopen.

Laten we een veelgebruikte klasse implementeren met de naam StroomGobbler die een InputStream:

private statische klasse StreamGobbler implementeert Runnable {private InputStream inputStream; particuliere consument consument; openbare StreamGobbler (InputStream inputStream, Consument consument) {this.inputStream = inputStream; this.consumer = consument; } @Override public void run () {nieuwe BufferedReader (nieuwe InputStreamReader (inputStream)). Lines () .forEach (consument); }}

OPMERKING: Deze klasse implementeert het Runnable interface, wat betekent dat het door iedereen kan worden uitgevoerd Uitvoerder.

4. Runtime.exec ()

Een methodeaanroep naar Runtime.exec () is een eenvoudige, nog niet aanpasbare manier om een ​​nieuw subproces te spawnen.

In het volgende voorbeeld zullen we een directorylijst van de homedirectory van een gebruiker opvragen en deze naar de console afdrukken:

String homeDirectory = System.getProperty ("user.home"); Proces proces; 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 = nieuwe StreamGobbler (process.getInputStream (), System.out :: println); Executors.newSingleThreadExecutor (). Submit (streamGobbler); int exitCode = process.waitFor (); beweren exitCode == 0;

5. ProcessBuilder

Voor de tweede implementatie van ons computerprobleem gebruiken we een ProcessBuilder. Dit heeft de voorkeur boven de Looptijd aanpak omdat we enkele details kunnen aanpassen.

We kunnen bijvoorbeeld:

  • verander de werkmap waarin onze shell-opdracht wordt uitgevoerd builder.directory ()
  • een aangepaste sleutel / waardetoewijzing instellen als omgeving met behulp van builder.environment ()
  • leiden invoer- en uitvoerstromen om naar aangepaste vervangingen
  • erven ze allebei aan de stromen van de stroom JVM proces gebruiken bouwer.inheritIO ()
ProcessBuilder builder = nieuwe ProcessBuilder (); if (isWindows) {builder.command ("cmd.exe", "/ c", "dir"); } else {builder.command ("sh", "-c", "ls"); } builder.directory (nieuw bestand (System.getProperty ("user.home"))); Proces proces = builder.start (); StreamGobbler streamGobbler = nieuwe StreamGobbler (process.getInputStream (), System.out :: println); Executors.newSingleThreadExecutor (). Submit (streamGobbler); int exitCode = process.waitFor (); beweren exitCode == 0;

6. Conclusie

Zoals we in deze korte tutorial hebben gezien, kunnen we een shell-commando uitvoeren in Java op twee verschillende manieren.

Over het algemeen, als u van plan bent om de uitvoering van het voortgebrachte proces aan te passen, bijvoorbeeld om de werkmap te wijzigen, zou u moeten overwegen om een ProcessBuilder.

Zoals altijd vind je de bronnen op GitHub.