Skip to content

Archives

  • januar 2022
  • december 2021
  • november 2021
  • oktober 2021
  • september 2021

Categories

  • Ingen kategorier
Trend RepositoryArticles and guides
Articles

Udførelse af shell-kommandoer i Java

On oktober 23, 2021 by admin
  • Indledning
  • Runtime.exec()
  • Udførelse af en kommando fra String
  • Angiv arbejdskatalog
  • Anvendelse af miljøvariabler
  • Kørsel af .bat- og .sh-filer
  • ProcessBuilder
  • ProcessBuilder: I stedet for at kunne levere en enkelt streng, f.eks. cmd /c dir, er vi i dette tilfælde nødt til at opdele den. Hvis vi f.eks. ville liste filerne i mappen C:/Users som før, ville vi gøre: ProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command("cmd", "/c", "dir C:\Users");Process process = processBuilder.start();printResults(process);
  • ProcessBuilder: I stedet for at angive arbejdsmappen via kommandoen kan vi indstille den programmatisk: processBuilder.command("cmd", "/c", "dir").directory(new File("C:\Users\"));
  • ProcessBuilder: Environment Variables
  • ProcessBuilder: Hvis du vil køre en fil, skal vi igen bare forsyne ProcessBuilder-instansen med de nødvendige oplysninger: processBuilder .command("cmd", "/c", "start", "file.bat") .directory(new File("C:\Users\User\Desktop"));Process process = processBuilder.start();
  • Konklusion

Indledning

I denne artikel vil vi se på, hvordan vi kan udnytte Runtime– og ProcessBuilder-klasserne til at udføre shell-kommandoer og scripts med Java.

Vi bruger computere til at automatisere mange ting i vores daglige arbejde. Systemadministratorer kører hele tiden mange kommandoer, hvoraf nogle er meget gentagende og kræver minimale ændringer mellem kørslerne.

Denne proces er også moden til automatisering. Der er ingen grund til at køre alting manuelt. Ved hjælp af Java kan vi køre enkelte eller flere shell-kommandoer, udføre shell-scripts, køre terminalen/kommandoprompten, indstille arbejdskataloger og manipulere miljøvariabler via kerneklasser.

Runtime.exec()

Klassen Runtime i Java er en klasse på højt niveau, der er til stede i hver eneste Java-applikation. Gennem den kommunikerer selve programmet med det miljø, det befinder sig i.

Gennem at udtrække den runtime, der er knyttet til vores program via getRuntime()-metoden, kan vi bruge exec()-metoden til at udføre kommandoer direkte eller køre .bat/.sh-filer.

exec()-metoden tilbyder et par overloadede variationer:

  • public Process exec(String command) – Udfører kommandoen indeholdt i command i en separat proces.
  • public Process exec(String command, String envp) – Udfører command, med et array af miljøvariabler. De leveres som et array af strenge, der følger formatet name=value.
  • public Process exec(String command, String envp, File dir) – Udfører command, med de angivne miljøvariabler, fra mappen dir.
  • public Process exec(String cmdArray) – Udfører en kommando i form af et array af strenge.
  • public Process exec(String cmdArray, String envp) – Udfører en kommando med de angivne miljøvariabler.
  • public Process exec(String cmdarray, String envp, File dir) – Udfører en kommando med de angivne miljøvariabler inde fra mappen dir.

Det er værd at bemærke, at disse processer køres eksternt fra fortolkeren og vil være systemafhængige.

Det er også værd at bemærke forskellen mellem String command og String cmdArray. De opnår den samme ting. En command er alligevel opdelt i et array, så brug af en af disse to burde give de samme resultater.

Det er op til dig at afgøre, om exec("dir /folder") eller exec(new String{"dir", "/folder"} er det, du vil bruge.

Lad os skrive et par eksempler for at se, hvordan disse overloadede metoder adskiller sig fra hinanden.

Udførelse af en kommando fra String

Lad os starte med den enkleste fremgangsmåde ud af disse tre:

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

Kørsel af denne kode vil udføre den kommando, som vi har leveret i String-format. Vi kan dog ikke se noget, når vi kører dette.

For at validere, om dette kørte korrekt, skal vi få fat i process-objektet. Lad os bruge en BufferedReader til at tage et kig på, hvad der foregår:

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, når vi kører denne metode efter exec()-metoden, bør det give noget i retning af:

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

Husk, at vi bliver nødt til at udtrække procesoplysningerne fra Process-instanserne, når vi gennemgår andre eksempler.

Angiv arbejdskatalog

Hvis du gerne vil køre en kommando fra f.eks. en bestemt mappe, ville vi gøre noget i stil med:

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

Her har vi forsynet exec()-metoden med en command, en null til nye miljøvariabler og en new File(), som er angivet som vores arbejdskatalog.

Den tilføjelse af cmd /c før en kommando som dir er værd at bemærke.

Da jeg arbejder på Windows, åbner dette cmd, og /c udfører den efterfølgende kommando. I dette tilfælde er det dir.

Grunden til, at dette ikke var obligatorisk for ping-eksemplet, men er obligatorisk for dette eksempel, er pænt besvaret af en SO-bruger.

Kørsel af det foregående stykke kode vil resultere i:

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

Lad os se på, hvordan vi kunne levere den foregående kommando i flere individuelle dele, i stedet for en enkelt String:

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

Kørsel af dette stykke kode vil også resultere i:

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

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

I sidste ende vil den indtastede kommando uanset fremgangsmåden – ved hjælp af en enkelt String eller et String-array – altid blive opdelt i et array, inden den bliver behandlet af den underliggende logik.

Hvilken du vil bruge koger blot ned til, hvilken du finder mere læsbar.

Anvendelse af miljøvariabler

Lad os se på, hvordan vi kan bruge miljøvariabler:

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

Vi kan angive så mange miljøvariabler, som vi vil, inden for String-arrayet. Her har vi lige udskrevet værdien af var1 ved hjælp af echo.

Kørsel af denne kode vil give:

value1

Kørsel af .bat- og .sh-filer

I nogle tilfælde er det bare meget nemmere at aflaste alt til en fil og køre den fil i stedet for at tilføje alt programmatisk.

Afhængigt af dit styresystem bruger du enten .bat eller .sh-filer. Lad os oprette en med indholdet:

echo Hello World

Derpå bruger vi den samme fremgangsmåde som før:

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

Dette vil åbne kommandoprompten og køre .bat-filen i den arbejdskatalog, vi har indstillet.

Kørsel af denne kode resulterer sikkert nok i:

Med alle de overbelastede exec()-signaturer taget hånd om, lad os tage et kig på ProcessBuilder-klassen, og hvordan vi kan udføre kommandoer ved hjælp af den.

ProcessBuilder

ProcessBuilder er den underliggende mekanisme, der kører kommandoerne, når vi bruger Runtime.getRuntime().exec()-metoden:

/** * 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 for Runtime-klassen

Tager vi et kig på, hvordan ProcessBuilder tager vores input fra exec()-metoden og kører kommandoen, får vi også et godt indblik i, hvordan vi kan bruge den.

Den accepterer en String cmdarray, og det er nok til at få den til at køre. Alternativt kan vi forsyne den med valgfrie argumenter som String envp og File dir.

Lad os undersøge disse muligheder.

ProcessBuilder: I stedet for at kunne levere en enkelt streng, f.eks. cmd /c dir, er vi i dette tilfælde nødt til at opdele den. Hvis vi f.eks. ville liste filerne i mappen C:/Users som før, ville vi gøre:

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

For rent faktisk at udføre en Process kører vi kommandoen start() og tildeler den returnerede værdi til en Process-instans.

Kørsel af denne kode vil give:

 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

Denne fremgangsmåde er dog ikke bedre end den foregående. Det, der er nyttigt ved ProcessBuilder-klassen, er, at den kan tilpasses. Vi kan indstille ting programmatisk, ikke kun via kommandoer.

ProcessBuilder: I stedet for at angive arbejdsmappen via kommandoen kan vi indstille den programmatisk:

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

Her har vi indstillet arbejdsmappen til at være den samme som før, men vi har flyttet denne definition ud af selve kommandoen. Hvis du kører denne kode, får du det samme resultat som i det sidste eksempel.

ProcessBuilder: Environment Variables

Ved hjælp af ProcessBuilders metoder er det nemt at hente en liste over miljøvariabler i form af en Map. Det er også nemt at indstille miljøvariabler, så dit program kan bruge dem.

Lad os hente de miljøvariabler, der er tilgængelige i øjeblikket, og derefter tilføje nogle til senere brug:

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

Her har vi pakket de returnerede miljøvariabler ind i en Map og kørt en forEach() på den for at udskrive værdierne til vores konsol.

Kørsel af denne kode vil give en liste over de miljøvariabler, du har på din maskine:

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

Nu skal vi tilføje en miljøvariabel til denne liste og bruge den:

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

Kørsel af denne kode vil give:

value1

Når programmet er færdig med at køre, vil denne variabel naturligvis ikke forblive på listen.

ProcessBuilder: Hvis du vil køre en fil, skal vi igen bare forsyne ProcessBuilder-instansen med de nødvendige oplysninger:

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

Kørsel af denne kode resulterer i, at kommandoprompten åbner og udfører .bat-filen:

Konklusion

I denne artikel har vi udforsket eksempler på at køre shell-kommandoer i Java. Vi har brugt Runtime– og ProcessBuilder-klasserne til dette.

Med Java kan vi køre enkelte eller flere shell-kommandoer, udføre shell-scripts, køre terminalen/kommandoprompten, indstille arbejdskataloger og manipulere miljøvariabler via kerneklasser.

Skriv et svar Annuller svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

Arkiver

  • januar 2022
  • december 2021
  • november 2021
  • oktober 2021
  • september 2021

Meta

  • Log ind
  • Indlægsfeed
  • Kommentarfeed
  • 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