Skip to content

Archives

  • januari 2022
  • december 2021
  • november 2021
  • oktober 2021
  • september 2021

Categories

  • Geen categorieën
Trend RepositoryArticles and guides
Articles

Shell commando’s uitvoeren in Java

On oktober 23, 2021 by admin
  • Inleiding
  • Runtime.exec()
  • Uitvoeren van een commando van String
  • Specificeer de Werkdirectory
  • Omgevingsvariabelen gebruiken
  • Het uitvoeren van .bat en .sh bestanden
  • ProcessBuilder
  • ProcessBuilder: Executing Command from Strings
  • ProcessBuilder: Specificeer de werkdirectory
  • ProcessBuilder: Omgevingsvariabelen
  • ProcessBuilder: Running .bat and .sh Files
  • Conclusie

Inleiding

In dit artikel bekijken we hoe we de Runtime en ProcessBuilder classes kunnen gebruiken om shell commando’s en scripts uit te voeren met Java.

We gebruiken computers om veel dingen in ons dagelijks werk te automatiseren. Systeembeheerders voeren voortdurend veel commando’s uit, waarvan sommige zeer repetitief zijn en tussen de runs door minimale veranderingen vereisen.

Dit proces is ook rijp voor automatisering. Het is niet nodig om alles handmatig uit te voeren. Met Java kunnen we enkele of meerdere shell commando’s uitvoeren, shell scripts uitvoeren, de terminal/command prompt starten, werkdirectories instellen en omgevingsvariabelen manipuleren via core classes.

Runtime.exec()

De Runtime class in Java is een high-level class, die in elke Java applicatie aanwezig is. Via deze klasse communiceert de applicatie zelf met de omgeving waarin het zich bevindt.

Door de runtime te extraheren die aan onze applicatie is gekoppeld via de getRuntime() methode, kunnen we de exec() methode gebruiken om direct commando’s uit te voeren of .bat/.sh bestanden uit te voeren.

De exec() methode biedt een paar overloaded variaties:

  • public Process exec(String command) – Voert het commando uit dat in command in een apart proces staat.
  • public Process exec(String command, String envp) – Voert de command uit, met een array van omgevingsvariabelen. Ze worden geleverd als een array van Strings, volgens het name=value formaat.
  • public Process exec(String command, String envp, File dir) – Voert de command uit, met de gespecificeerde omgevingsvariabelen, vanuit de dir directory.
  • public Process exec(String cmdArray) – Voert een commando uit in de vorm van een array van Strings.
  • public Process exec(String cmdArray, String envp) – Voert een commando uit met de gespecificeerde omgevingsvariabelen.
  • public Process exec(String cmdarray, String envp, File dir) – Voert een commando uit, met de gespecificeerde omgevingsvariabelen, vanuit de dir directory.

Het is de moeite waard om op te merken dat deze processen extern van de interpreter worden uitgevoerd en systeemafhankelijk zullen zijn.

Wat ook de moeite waard is om op te merken, is het verschil tussen String command en String cmdArray. Ze bereiken hetzelfde. Een command wordt toch al in een array opgedeeld, dus het gebruik van een van deze twee zou dezelfde resultaten moeten opleveren.

Het is aan u om te beslissen of exec("dir /folder") of exec(new String{"dir", "/folder"} is wat u wilt gebruiken.

Laten we een paar voorbeelden schrijven om te zien hoe deze overloaded methoden van elkaar verschillen.

Uitvoeren van een commando van String

Laten we beginnen met de eenvoudigste aanpak van deze drie:

Process process = Runtime.getRuntime().exec("ping www.stackabuse.com");

Het uitvoeren van deze code zal het commando uitvoeren dat we in String formaat hebben aangeleverd. We zien echter niets als we dit uitvoeren.

Om te valideren of dit correct is uitgevoerd, willen we het process object te pakken krijgen. Laten we een BufferedReader gebruiken om te kijken wat er gebeurt:

public static void printResults(Process process) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = reader.readLine()) != null) { System.out.println(line); }}

Nu, als we deze methode uitvoeren na de exec() methode, zou het iets moeten opleveren in de trant van:

Pinging www.stackabuse.com with 32 bytes of data:Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Ping statistics for 104.18.57.23: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),Approximate round trip times in milli-seconds: Minimum = 21ms, Maximum = 21ms, Average = 21ms

Houd in gedachten dat we de proces informatie uit de Process instanties moeten halen als we door andere voorbeelden gaan.

Specificeer de Werkdirectory

Als u een commando wilt uitvoeren vanuit, laten we zeggen, een bepaalde map, dan zouden we iets doen in de trant van:

Process process = Runtime.getRuntime() .exec("cmd /c dir", null, new File("C:\Users\")); //.exec("sh -c ls", null, new File("Pathname")); for non-Windows usersprintResults(process);

Hier hebben we de exec() methode voorzien van een command, een null voor nieuwe omgevingsvariabelen en een new File() die is ingesteld als onze werkdirectory.

De toevoeging van cmd /c voor een commando zoals dir is de moeite van het opmerken waard.

Omdat ik onder Windows werk, opent dit de cmd en /c voert het daaropvolgende commando uit. In dit geval is dat dir.

De reden waarom dit niet verplicht was voor het ping voorbeeld, maar wel voor dit voorbeeld, is mooi beantwoord door een SO gebruiker.

Het uitvoeren van het vorige stukje code zal resulteren in:

Volume in drive C has no label. Volume Serial Number is XXXX-XXXX Directory of C:\Users08/29/2019 05:01 PM <DIR> .08/29/2019 05:01 PM <DIR> ..08/18/2016 09:11 PM <DIR> Default.migrated08/29/2019 05:01 PM <DIR> Public05/15/2020 11:08 AM <DIR> User 0 File(s) 0 bytes 5 Dir(s) 212,555,214,848 bytes free

Laten we eens kijken hoe we het vorige commando in verschillende afzonderlijke delen zouden kunnen leveren, in plaats van een enkele String:

Process process = Runtime.getRuntime().exec( new String{"cmd", "/c", "dir"}, null, new File("C:\Users\")); printResults(process);

Het uitvoeren van dit stukje code zal ook resulteren in:

Volume in drive C has no label. Volume Serial Number is XXXX-XXXX Directory of C:\Users08/29/2019 05:01 PM <DIR> .08/29/2019 05:01 PM <DIR> ..08/18/2016 09:11 PM <DIR> Default.migrated08/29/2019 05:01 PM <DIR> Public05/15/2020 11:08 AM <DIR> User 0 File(s) 0 bytes 5 Dir(s) 212,542,808,064 bytes free

Ultime, ongeacht de aanpak – met behulp van een enkele String of een String array, de opdracht die u invoert zal altijd worden opgesplitst in een array alvorens te worden verwerkt door onderliggende logica.

Welke u wilt gebruiken, komt gewoon neer op welke u leesbaarder vindt.

Omgevingsvariabelen gebruiken

Laten we eens kijken hoe we omgevingsvariabelen kunnen gebruiken:

Process process = Runtime.getRuntime().exec( "cmd /c echo %var1%", new String{"var1=value1"}); printResults(process);

We kunnen zo veel omgevingsvariabelen opgeven als we willen binnen de String-array. Hier hebben we zojuist de waarde van var1 afgedrukt met behulp van echo.

Het uitvoeren van deze code levert het volgende op:

value1

Het uitvoeren van .bat en .sh bestanden

Soms is het gewoon veel gemakkelijker om alles in een bestand te laden en dat bestand uit te voeren in plaats van alles programmatisch toe te voegen.

Afhankelijk van uw besturingssysteem, zou u .bat of .sh bestanden gebruiken. Laten we er een maken met de inhoud:

echo Hello World

Dan, laten we dezelfde aanpak gebruiken als eerder:

Process process = Runtime.getRuntime().exec( "cmd /c start file.bat", null, new File("C:\Users\User\Desktop\"));

Dit zal de commando prompt openen en het .bat bestand uitvoeren in de werkdirectory die we hebben ingesteld.

Het uitvoeren van deze code resulteert in:

Met alle overbelaste exec() handtekeningen, laten we eens kijken naar de ProcessBuilder klasse en hoe we commando’s kunnen uitvoeren met behulp daarvan.

ProcessBuilder

ProcessBuilder is het onderliggende mechanisme dat de commando’s uitvoert wanneer we de Runtime.getRuntime().exec() methode gebruiken:

/** * Executes the specified command and arguments in a separate process with * the specified environment and working directory. *...*/public Process exec(String cmdarray, String envp, File dir) throws IOException { return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start();}

JavaDocs voor de Runtime klasse

Een blik op hoe de ProcessBuilder onze invoer van de exec() methode neemt en het commando uitvoert, geeft ons een goed idee van hoe we het ook kunnen gebruiken.

Het accepteert een String cmdarray, en dat is genoeg om het aan de gang te krijgen. Als alternatief kunnen we het voorzien van optionele argumenten, zoals de String envp en File dir.

Laten we deze opties eens verkennen.

ProcessBuilder: Executing Command from Strings

In plaats van een enkele String op te kunnen geven, zoals cmd /c dir, zullen we het in dit geval moeten opsplitsen. Als we bijvoorbeeld de bestanden in de C:/Users directory willen zien, zoals voorheen, doen we:

ProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command("cmd", "/c", "dir C:\Users");Process process = processBuilder.start();printResults(process);

Om daadwerkelijk een Process uit te voeren, voeren we het start() commando uit en wijzen de geretourneerde waarde toe aan een Process instantie.

Het uitvoeren van deze code levert op:

 Volume in drive C has no label. Volume Serial Number is XXXX-XXXX Directory of C:\Users08/29/2019 05:01 PM <DIR> .08/29/2019 05:01 PM <DIR> ..08/18/2016 09:11 PM <DIR> Default.migrated08/29/2019 05:01 PM <DIR> Public05/15/2020 11:08 AM <DIR> User 0 File(s) 0 bytes 5 Dir(s) 212,517,294,080 bytes free

Deze aanpak is echter niet beter dan de vorige. Wat handig is met de ProcessBuilder klasse is dat het aanpasbaar is. We kunnen dingen programmatisch instellen, niet alleen via commando’s.

ProcessBuilder: Specificeer de werkdirectory

In plaats van de werkdirectory via het commando op te geven, stellen we die programmatisch in:

processBuilder.command("cmd", "/c", "dir").directory(new File("C:\Users\"));

Hier hebben we de werkdirectory op dezelfde als voorheen ingesteld, maar we hebben die definitie uit het commando zelf verplaatst. Het uitvoeren van deze code zal hetzelfde resultaat opleveren als het laatste voorbeeld.

ProcessBuilder: Omgevingsvariabelen

Met behulp van ProcessBuilders methoden is het eenvoudig om een lijst met omgevingsvariabelen op te vragen in de vorm van een Map. Het is ook eenvoudig om omgevingsvariabelen in te stellen, zodat uw programma ze kan gebruiken.

Laten we de omgevingsvariabelen opvragen die op dit moment beschikbaar zijn en er dan een paar toevoegen voor later gebruik:

ProcessBuilder processBuilder = new ProcessBuilder();Map<String, String> environmentVariables = processBuilder.environment();environmentVariables.forEach((key, value) -> System.out.println(key + value));

Hier hebben we de geretourneerde omgevingsvariabelen verpakt in een Map en er een forEach() op uitgevoerd om de waarden op onze console uit te printen.

Het uitvoeren van deze code levert een lijst op van de omgevingsvariabelen die u op uw machine hebt:

DriverDataC:\Windows\System32\Drivers\DriverDataHerokuPathE:\HerokuProgramDataC:\ProgramData...

Nu, laten we een omgevingsvariabele aan die lijst toevoegen en hem gebruiken:

environmentVariables.put("var1", "value1");processBuilder.command("cmd", "/c", "echo", "%var1%");Process process = processBuilder.start();printResults(process);

Het uitvoeren van deze code levert op:

value1

Natuurlijk, als het programma klaar is met draaien, zal deze variabele niet in de lijst blijven.

ProcessBuilder: Running .bat and .sh Files

Als u een bestand wilt uitvoeren, kunt u de ProcessBuilder instantie voorzien van de benodigde informatie:

processBuilder .command("cmd", "/c", "start", "file.bat") .directory(new File("C:\Users\User\Desktop"));Process process = processBuilder.start();

Het uitvoeren van deze code resulteert in het openen van de opdrachtprompt en het uitvoeren van het .bat bestand:

Conclusie

In dit artikel hebben we voorbeelden bekeken van het uitvoeren van shell commando’s in Java. We hebben hiervoor de klassen Runtime en ProcessBuilder gebruikt.

Met Java kunnen we enkelvoudige of meervoudige shell-commando’s uitvoeren, shell-scripts uitvoeren, de terminal/command prompt starten, werkdirectories instellen en omgevingsvariabelen manipuleren via core klassen.

Geef een antwoord Antwoord annuleren

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Archieven

  • januari 2022
  • december 2021
  • november 2021
  • oktober 2021
  • september 2021

Meta

  • Inloggen
  • Berichten feed
  • Reacties feed
  • WordPress.org
  • DeutschDeutsch
  • NederlandsNederlands
  • SvenskaSvenska
  • DanskDansk
  • EspañolEspañol
  • FrançaisFrançais
  • PortuguêsPortuguês
  • ItalianoItaliano
  • RomânăRomână
  • PolskiPolski
  • ČeštinaČeština
  • MagyarMagyar
  • SuomiSuomi
  • 日本語日本語

Copyright Trend Repository 2022 | Theme by ThemeinProgress | Proudly powered by WordPress