Hoppa till innehåll

Archives

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

Categories

  • Inga kategorier
Trend RepositoryArticles and guides
Articles

Utföra skalkommandon i Java

On oktober 23, 2021 by admin
  • Inledning
  • Runtime.exec()
  • Exekvera ett kommando från String
  • Ange arbetskatalogen
  • Användning av miljövariabler
  • Körning av .bat- och .sh-filer
  • ProcessBuilder
  • ProcessBuilder: I stället för att kunna tillhandahålla en enda sträng, till exempel cmd /c dir, måste vi dela upp den i det här fallet. Om vi till exempel vill lista filerna i katalogen C:/Users som tidigare skulle vi göra: ProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command("cmd", "/c", "dir C:\Users");Process process = processBuilder.start();printResults(process);
  • ProcessBuilder: processBuilder.command("cmd", "/c", "dir").directory(new File("C:\Users\"));
  • ProcessBuilder: Environment Variables
  • ProcessBuilder: Om du vill köra en fil är det återigen bara att förse ProcessBuilder-instansen med nödvändig information: processBuilder .command("cmd", "/c", "start", "file.bat") .directory(new File("C:\Users\User\Desktop"));Process process = processBuilder.start();
  • Slutsats

Inledning

I den här artikeln tittar vi på hur vi kan utnyttja klasserna Runtime och ProcessBuilder för att utföra skalkommandon och skript med Java.

Vi använder datorer för att automatisera många saker i vårt dagliga arbete. Systemadministratörer kör många kommandon hela tiden, varav vissa är mycket repetitiva och kräver minimala ändringar mellan körningarna.

Denna process är också mogen för automatisering. Det finns ingen anledning att köra allting manuellt. Med hjälp av Java kan vi köra enstaka eller flera skalkommandon, exekvera skalskript, köra terminalen/kommandoprompten, ställa in arbetskataloger och manipulera miljövariabler genom kärnklasser.

Runtime.exec()

Klassen Runtime i Java är en klass på hög nivå som finns i varje enskild Java-applikation. Genom den kommunicerar själva applikationen med den miljö den befinner sig i.

Då vi extraherar den körtid som är associerad med vår applikation via getRuntime()-metoden kan vi använda exec()-metoden för att utföra kommandon direkt eller köra .bat/.sh-filer.

Metoden exec() erbjuder några överladdade varianter:

  • public Process exec(String command) – Exekverar kommandot som finns i command i en separat process.
  • public Process exec(String command, String envp) – Exekverar command, med en array av miljövariabler. De tillhandahålls som en array av strängar, enligt formatet name=value.
  • public Process exec(String command, String envp, File dir) – Exekverar command, med de angivna miljövariablerna, från katalogen dir.
  • public Process exec(String cmdArray) – Exekverar ett kommando i form av en array av strängar.
  • public Process exec(String cmdArray, String envp) – Exekverar ett kommando med de angivna miljövariablerna.
  • public Process exec(String cmdarray, String envp, File dir) – Utför ett kommando med de angivna miljövariablerna från katalogen dir.

Det är värt att notera att dessa processer körs externt från tolken och kommer att vara systemberoende.

Vad som också är värt att notera är skillnaden mellan String command och String cmdArray. De uppnår samma sak. En command delas ändå upp i en array, så att använda någon av dessa två bör ge samma resultat.

Det är upp till dig att avgöra om exec("dir /folder") eller exec(new String{"dir", "/folder"} är det du vill använda.

Låt oss skriva några exempel för att se hur dessa överladdade metoder skiljer sig från varandra.

Exekvera ett kommando från String

Låt oss börja med det enklaste tillvägagångssättet av dessa tre:

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

Att köra den här koden kommer att exekvera kommandot vi har angett i String-format. Vi ser dock ingenting när vi kör detta.

För att bekräfta om detta kördes korrekt vill vi få tag på process-objektet. Låt oss använda en BufferedReader för att ta en titt på vad som händer:

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

När vi nu kör den här metoden efter exec()-metoden bör den ge något i stil med:

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

Håll i minnet att vi måste extrahera processinformationen från Process-instanserna när vi går igenom andra exempel.

Ange arbetskatalogen

Om du vill köra ett kommando från till exempel en viss mapp gör vi något 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);

Här har vi försett exec()-metoden med en command, en null för nya miljövariabler och en new File() som är satt som vår arbetskatalog.

Har man lagt till cmd /c före ett kommando som dir är det värt att notera.

Då jag arbetar i Windows öppnar detta cmd och /c utför det efterföljande kommandot. I det här fallet är det dir.

Anledningen till att detta inte var obligatoriskt för ping-exemplet, men är obligatoriskt för det här exemplet besvaras snyggt av en SO-användare.

Att köra föregående kodstycke kommer att resultera 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

Vi kan ta en titt på hur vi skulle kunna leverera föregående kommando i flera enskilda delar, istället för en enda sträng:

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

Att köra detta kodstycke kommer också att resultera 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,542,808,064 bytes free

Oavsett vilket tillvägagångssätt som används – en enskild sträng eller en strängarray – kommer kommandot du matar in alltid att delas upp i en array innan det bearbetas av den underliggande logiken.

Vilken du vill använda kokar bara ner till vilken du tycker är mer läsbar.

Användning av miljövariabler

Låt oss ta en titt på hur vi kan använda miljövariabler:

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

Vi kan tillhandahålla så många miljövariabler som vi vill inom String arrayen. Här har vi just skrivit ut värdet på var1 med hjälp av echo.

Körning av den här koden ger följande resultat:

value1

Körning av .bat- och .sh-filer

Under vissa omständigheter är det mycket enklare att avlasta allting till en fil och köra den filen i stället för att lägga till allting programmässigt.

Avhängigt av ditt operativsystem använder du antingen .bat eller .sh-filer. Låt oss skapa en sådan med följande innehåll:

echo Hello World

Därefter använder vi samma tillvägagångssätt som tidigare:

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

Detta öppnar kommandotolken och kör .bat-filen i arbetskatalogen som vi har ställt in.

Att köra den här koden resulterar säkert nog i:

Med alla överbelastade exec()-signaturer omhändertagna, låt oss ta en titt på ProcessBuilder-klassen och hur vi kan exekvera kommandon med hjälp av den.

ProcessBuilder

ProcessBuilder är den underliggande mekanismen som kör kommandona när vi använder 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 the Runtime class

Om vi tar en titt på hur ProcessBuilder tar emot vår inmatning från exec()-metoden och kör kommandot, får vi en bra idé om hur den också kan användas.

Den tar emot en String cmdarray, och det räcker för att få igång den. Alternativt kan vi förse den med valfria argument som String envp och File dir.

Låt oss utforska dessa alternativ.

ProcessBuilder: I stället för att kunna tillhandahålla en enda sträng, till exempel cmd /c dir, måste vi dela upp den i det här fallet. Om vi till exempel vill lista filerna i katalogen C:/Users som tidigare skulle vi göra:

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

För att faktiskt exekvera en Process kör vi kommandot start() och tilldelar det returnerade värdet till en Process-instans.

Körning av den här koden kommer att ge:

 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

Det här tillvägagångssättet är dock inte bättre än det föregående. Det som är användbart med ProcessBuilder-klassen är att den är anpassningsbar. Vi kan ställa in saker programmatiskt, inte bara via kommandon.

ProcessBuilder:

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

Istället för att ange arbetskatalogen via kommandot kan vi ställa in den programmatiskt:

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

Här har vi ställt in arbetskatalogen på samma sätt som tidigare, men vi har flyttat den definitionen ut ur själva kommandot. Om du kör den här koden får du samma resultat som i det senaste exemplet.

ProcessBuilder: Environment Variables

Med hjälp av ProcessBuilders metoder är det enkelt att hämta en lista över miljövariabler i form av en Map. Det är också enkelt att ställa in miljövariabler så att ditt program kan använda dem.

Låt oss hämta de miljövariabler som för närvarande är tillgängliga och sedan lägga till några för senare användning:

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

Här har vi packat de returnerade miljövariablerna i en Map och kört en forEach() på den för att skriva ut värdena till vår konsol.

Körning av den här koden ger en lista över de miljövariabler du har på din maskin:

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

Nu lägger vi till en miljövariabel i listan och använder den:

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

Körning av den här koden ger:

value1

När programmet väl är färdigt att köras kommer den här variabeln förstås inte att finnas kvar i listan.

ProcessBuilder: Om du vill köra en fil är det återigen bara att förse ProcessBuilder-instansen med nödvändig information:

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

Körningen av den här koden resulterar i att kommandotolken öppnas och att .bat-filen exekveras:

Slutsats

I den här artikeln har vi undersökt exempel på hur man kan köra skalkommandon i Java. Vi har använt klasserna Runtime och ProcessBuilder för att göra detta.

Med hjälp av Java kan vi köra enstaka eller flera skalkommandon, exekvera skalskript, köra terminalen/kommandoprompten, ställa in arbetskataloger och manipulera miljövariabler genom kärnklasser.

Lämna ett svar Avbryt svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Arkiv

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

Meta

  • Logga in
  • Flöde för inlägg
  • Flöde för kommentarer
  • 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
  • 日本語日本語

Upphovsrätt Trend Repository 2022 | Tema av ThemeinProgress | Drivs med WordPress