Sådan kører du systemkommandoer fra Ruby

Hvis du vil køre en ekstern kommando fra Ruby…

…som wkhtmltopdf til at konvertere en HTML-fil til en PDF.

Der er et par Ruby-metoder, du kan bruge.

Afhængigt af hvilken metode du bruger, vil du få forskellige resultater.

Lad os udforske disse metoder sammen!

Ruby-systemmetoden

Ruby-systemmetoden er den enkleste måde at køre en ekstern kommando på.

Den ser således ud:

system("ls")

Bemærk, at system udskriver kommandoudgangen, mens den sker.

Og systemet vil også få dit Ruby-program til at vente, indtil kommandoen er færdig.

Prøv dette:

system("sleep 2")

Der er måder at køre kommandoer i baggrunden på, som vi vil se senere.

Systemet kan returnere 3 mulige værdier:

  • true hvis kommandoen virkede
  • false hvis kommandoen returnerer en fejlkode
  • nil hvis udførelsen af kommandoen mislykkes (kommando ikke fundet)

Du kan få exit-statuskoden for den sidste eksterne kommando, du kørte, med den globale variabel $?. Denne statuskode kan give dig flere oplysninger om, hvorfor kommandoen mislykkedes.

Hvad er shelludvidelse?

Når du kører en ekstern kommando med system, får du “shelludvidelse”-effekten.

Shelludvidelse er, når shell’en (sh/bash/zsh) tager nogle specialtegn (*, ? og ")# "best"

This will not change the current environment of your Ruby application.

%x / Kernel#`

If you want to get the output from the command you're running, instead of displaying it then you can use %x eller metoden Kernel#`.

De gør det samme.

Her er et eksempel:

`ls`

Et andet med %x:

%x|ls|

Disse to eksempler returnerer en streng med output fra ls-kommandoen.

Bemærk, at du stadig skal vente på, at kommandoen er færdig, medmindre du kører den i en tråd.

Sådan bruger du Fork + Exec til at køre eksterne kommandoer på en separat proces

Fork laver en kopi af din nuværende proces (din Ruby-app), hvorefter du kan erstatte denne kopi med en anden proces ved hjælp af exec.

Bemærk: Gaffelmetoden er ikke tilgængelig på Windows.

Dette er et populært mønster i Unix-verdenen.

Sådan fungerer det:

fork { exec("ls") }

Dette vil køre ls på en anden proces & vise dens output.

Da denne kommando kører i en anden proces, vil den ikke blokere din Ruby-app fra at køre ligesom system-metoden eller %x.

Vigtigt:

Hvis du bruger exec uden fork, vil du erstatte din nuværende proces.

Det betyder, at dit Ruby-program slutter.

Sådan bruger du Popen-metoden til tovejskommunikation med et eksternt program

Hvis du har brug for:

  • Mere kontrol over processen
  • Tovejskommunikation

Så er IO.popen-metoden det, du leder efter.

I det følgende eksempel bruger jeg popen-metoden til at starte en irb proces og derefter sende noget input til den & og læse output.

Her er eksemplet:

r = IO.popen("irb", "r+")r.write "puts 123 + 1\n"3.times { puts r.gets }r.write "exit\n"

Denne rvariabel er et IO-objekt, det betyder, at du kan skrive & læse fra den som en almindelig fil.

Brug af popen betyder også, at din eksterne kommando kører på sin egen proces, så du ikke behøver at køre den på en tråd.

Der er også en popen3-metode i standardbiblioteket.

Den forskel med den almindelige popen er, at den opdeler almindelige output &-fejlmeddelelser i separate IO-objekter.

Slutning

Du har lært om de forskellige måder, du kan interagere med eksterne kommandoer i Ruby.

Vær forsigtig med disse!

Du må ikke sende nogen form for brugerinput ind i disse kommandoer, medmindre du vil have et sikkerhedsproblem i din Ruby-app.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.