Skip to content

Archives

  • tammikuu 2022
  • joulukuu 2021
  • marraskuu 2021
  • lokakuu 2021
  • syyskuu 2021

Categories

  • Ei kategorioita
Trend RepositoryArticles and guides
Articles

Shell-komentojen suorittaminen Javassa

On 23 lokakuun, 2021 by admin
  • Esittely
  • Runtime.exec()
  • Komennon suorittaminen Stringistä
  • Työskentelyhakemiston määrittäminen
  • Ympäristömuuttujien käyttäminen
  • .bat- ja .sh-tiedostojen suorittaminen
  • ProcessBuilder
  • ProcessBuilder: Komennon suorittaminen merkkijonoista
  • ProcessBuilder: Määritä työhakemisto
  • ProcessBuilder: Ympäristömuuttujat
  • ProcessBuilder: .bat- ja .sh-tiedostojen suorittaminen
  • Johtopäätös

Esittely

Tässä artikkelissa tarkastelemme, miten voimme hyödyntää Runtime– ja ProcessBuilder-luokkia suorittaaksemme shell-komentoja ja -skriptejä Javalla.

Käytämme tietokoneita automatisoidaksemme monia asioita päivittäisissä töissämme. Järjestelmänvalvojat suorittavat jatkuvasti monia komentoja, joista osa on hyvin toistuvia ja vaatii vain vähän muutoksia suoritusten välillä.

Tämäkin prosessi on kypsä automatisoitavaksi. Kaikkea ei tarvitse ajaa manuaalisesti. Javan avulla voimme ajaa yksittäisiä tai useita komentotulkkikomentoja, suorittaa komentotulkkiskriptejä, käyttää terminaalia/komentokehotetta, asettaa työhakemistoja ja manipuloida ympäristömuuttujia ydinluokkien avulla.

Runtime.exec()

Javan Runtime-luokka on korkean tason luokka, joka on läsnä jokaisessa Java-sovelluksessa. Sen kautta sovellus itse kommunikoi sen ympäristön kanssa, jossa se on.

Poistamalla sovellukseemme liittyvän runtime-luokan getRuntime()-metodin kautta voimme käyttää exec()-metodia komentojen suorittamiseen suoraan tai .bat/.sh-tiedostojen suorittamiseen.

exec()-metodi tarjoaa muutamia ylikuormitettuja variaatioita:

  • public Process exec(String command) – Suorittaa command:n sisältämän komennon erillisessä prosessissa.
  • public Process exec(String command, String envp) – Suorittaa command:n, jossa on joukko ympäristömuuttujia. Ne annetaan merkkijonomääränä, joka noudattaa muotoa name=value.
  • public Process exec(String command, String envp, File dir) – Suorittaa command:n ja määritetyt ympäristömuuttujat sisältävän komennon dir-hakemistosta.
  • public Process exec(String cmdArray) – Suorittaa komennon merkkijonomääränä.
  • public Process exec(String cmdArray, String envp) – Suorittaa komennon määritettyjen ympäristömuuttujien kanssa.
  • public Process exec(String cmdarray, String envp, File dir) – Suorittaa komennon, jossa on määritetyt ympäristömuuttujat, hakemistosta dir.

On syytä huomata, että näitä prosesseja ajetaan tulkin ulkopuolelta ja ne ovat järjestelmäriippuvaisia.

Huomionarvoista on myös String command:n ja String cmdArray:n ero. Niillä saavutetaan sama asia. command pilkotaan joka tapauksessa joukoksi, joten käyttämällä mitä tahansa näistä kahdesta pitäisi saada samat tulokset.

Sinusta riippuu, haluatko käyttää exec("dir /folder") vai exec(new String{"dir", "/folder"}.

Kirjoitetaanpa muutama esimerkki, jotta nähdään, miten nämä ylikuormitetut metodit eroavat toisistaan.

Komennon suorittaminen Stringistä

Aloitetaan näistä kolmesta yksinkertaisimmalla lähestymistavalla:

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

Tämän koodin suorittaminen suorittaa antamamme komennon String-muodossa. Emme kuitenkaan näe mitään, kun suoritamme tämän.

Varmistaaksemme, toimiiko tämä oikein, haluamme päästä käsiksi process-objektiin. Käyttäkäämme BufferedReader:tä, jotta voimme katsoa, mitä tapahtuu:

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

Nyt kun ajamme tämän metodin exec()-metodin jälkeen, sen pitäisi tuottaa jotakin seuraavanlaista:

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

Pitäkää mielessä, että meidän on poimittava prosessin tiedot Process-instansseista, kun käymme läpi muita esimerkkejä.

Työskentelyhakemiston määrittäminen

Jos haluaisit ajaa komennon esimerkiksi tietystä kansiosta, tekisimme jotakin seuraavanlaista:

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

Tässä olemme antaneet exec()-metodille command, null uusille ympäristömuuttujille ja new File(), joka asetetaan työskentelyhakemistoksi.

Huomionarvoista on lisätä cmd /c ennen komentoa, kuten dir.

Koska työskentelen Windowsissa, tämä avaa cmd ja /c suorittaa seuraavan komennon. Tässä tapauksessa se on dir.

Syy siihen, miksi tämä ei ollut pakollinen ping-esimerkissä, mutta on pakollinen tässä esimerkissä, on hienosti vastattu eräältä SO-käyttäjältä.

Edellisen koodinpätkän suorittaminen johtaa:

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

Katsotaanpa, miten voisimme toimittaa edellisen komennon useina yksittäisinä osina yhden merkkijonon sijaan:

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

Tämän koodinpätkän suorittaminen johtaa myös:

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

Loppujen lopuksi, riippumatta lähestymistavasta – yksittäisen merkkijonon tai merkkijonojoukon käyttämisestä – syötetty komento pilkotaan aina joukoksi ennen kuin se käsitellään taustalla olevassa logiikassa.

Kumpaa haluat käyttää, kiteytyy vain siihen, kumpi on mielestäsi luettavampi.

Ympäristömuuttujien käyttäminen

Katsotaanpa, miten voimme käyttää ympäristömuuttujia:

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

Voimme syöttää niin monta ympäristömuuttujaa kuin haluamme String-joukon sisällä. Tässä olemme juuri tulostaneet var1:n arvon käyttämällä echo.

Tämän koodin suorittaminen palauttaa:

value1

.bat- ja .sh-tiedostojen suorittaminen

Joskus on vain paljon helpompaa siirtää kaikki tiedostoon ja suorittaa tuo tiedosto sen sijaan, että lisättäisiin kaikki ohjelmallisesti.

Käyttöjärjestelmästäsi riippuen käytät joko .bat– tai .sh-tiedostoja. Luodaan sellainen, jonka sisältö on:

echo Hello World

Käytetään sitten samaa lähestymistapaa kuin aiemmin:

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

Tämä avaa komentorivin ja ajaa .bat-tiedoston asettamassamme työhakemistossa.

Tämän koodin suorittaminen johtaa varmasti seuraavaan tulokseen:

Kun kaikki ylikuormitetut exec()-signatuurit on hoidettu, katsotaanpa ProcessBuilder-luokkaa ja sitä, miten voimme suorittaa komentoja sen avulla.

ProcessBuilder

ProcessBuilder on taustalla oleva mekanismi, joka suorittaa komennot, kun käytämme Runtime.getRuntime().exec()-metodia:

/** * 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-luokka

Katsomalla, miten ProcessBuilder ottaa syötteemme exec()-metodista ja suorittaa komennon, saamme hyvän käsityksen siitä, miten sitä myös käytetään.

Se hyväksyy String cmdarray:n, ja se riittää käynnistämään sen. Vaihtoehtoisesti voimme antaa sille valinnaisia argumentteja, kuten String envp ja File dir.

Tutkitaanpa näitä vaihtoehtoja.

ProcessBuilder: Komennon suorittaminen merkkijonoista

Sen sijaan, että voisimme antaa yhden merkkijonon, kuten cmd /c dir, meidän on tässä tapauksessa pilkottava se. Jos haluaisimme esimerkiksi listata C:/Users-hakemistossa olevat tiedostot kuten aiemmin, tekisimme näin:

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

Toteuttaaksemme varsinaisesti Process:n, suoritamme start()-komennon ja annamme palautetun arvon Process-instanssille.

Tämän koodin suorittaminen antaa tulokseksi:

 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

Tämä lähestymistapa ei kuitenkaan ole yhtään sen parempi kuin edellinenkään. ProcessBuilder-luokassa on hyödyllistä se, että se on muokattavissa. Voimme asettaa asioita ohjelmallisesti, emme vain komentojen kautta.

ProcessBuilder: Määritä työhakemisto

Sen sijaan, että annamme työhakemiston komennon kautta, asetetaan se ohjelmallisesti:

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

Tässä asetamme työhakemiston samaksi kuin ennenkin, mutta olemme siirtäneet tuon määritelmän pois itse komennosta. Tämän koodin suorittaminen antaa saman tuloksen kuin edellisessä esimerkissä.

ProcessBuilder: Ympäristömuuttujat

Käyttämällä ProcessBuilder:n metodeja on helppo hakea lista ympäristömuuttujista Map:n muodossa. Ympäristömuuttujia on myös helppo asettaa niin, että ohjelmasi voi käyttää niitä.

Haastetaan tällä hetkellä käytettävissä olevat ympäristömuuttujat ja lisätään sitten joitakin myöhempää käyttöä varten:

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

Tässä olemme pakanneet palautetut ympäristömuuttujat Map:ksi ja ajaneet forEach():n sen päälle tulostaaksemme arvot konsolillemme.

Tämän koodin suorittaminen tuottaa listan koneellasi olevista ympäristömuuttujista:

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

Lisätään nyt ympäristömuuttuja tuohon listaan ja käytetään sitä:

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

Tämän koodin suorittaminen tuottaa:

value1

Tietenkään ohjelman suorituksen päätyttyä tämä muuttuja ei pysy enää listalla.

ProcessBuilder: .bat- ja .sh-tiedostojen suorittaminen

Jälleen kerran, jos haluat suorittaa tiedoston, annamme vain ProcessBuilder-instanssille tarvittavat tiedot:

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

Tämän koodin suorittaminen johtaa siihen, että komentokehote aukeaa ja suorittaa .bat-tiedoston:

Johtopäätös

Tässä artikkelissa tutustuimme esimerkeillä komentotulkkikomentojen suorittamiseen Javassa. Olemme käyttäneet tähän Runtime– ja ProcessBuilder-luokkia.

Javan avulla voimme suorittaa yksittäisiä tai useita komentotulkkikomentoja, suorittaa komentotulkkiskriptejä, ajaa terminaalin/komentokehotteen, asettaa työhakemistoja ja käsitellä ympäristömuuttujia ydinluokkien avulla.

Vastaa Peruuta vastaus

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *

Arkistot

  • tammikuu 2022
  • joulukuu 2021
  • marraskuu 2021
  • lokakuu 2021
  • syyskuu 2021

Meta

  • Kirjaudu sisään
  • Sisältösyöte
  • Kommenttisyöte
  • 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