How to Run System Commands From Ruby

Als u een extern commando vanuit Ruby wilt uitvoeren…

…zoals wkhtmltopdf om een HTML-bestand om te zetten in een PDF.

Er zijn een paar Ruby-methoden die u kunt gebruiken.

Hoe afhankelijk van de methode die u gebruikt, krijgt u verschillende resultaten.

Laten we deze methoden eens samen verkennen!

De Ruby System Method

De Ruby system method is de eenvoudigste manier om een extern commando uit te voeren.

Het ziet er als volgt uit:

system("ls")

Merk op dat system de uitvoer van het commando zal afdrukken terwijl het gebeurt.

Ook zal het systeem uw Ruby-programma laten wachten tot het commando klaar is.

Probeer dit:

system("sleep 2")

Er zijn manieren om commando’s op de achtergrond uit te voeren, zoals we later zullen zien.

Het systeem kan 3 mogelijke waarden teruggeven:

  • true als de opdracht werkte
  • false als de opdracht een foutcode teruggeeft
  • nil als de uitvoering van de opdracht mislukt (opdracht niet gevonden)

U kunt de exit-statuscode krijgen van de laatste externe opdracht die u hebt uitgevoerd met de globale variabele $?. Deze statuscode kan u meer informatie geven over waarom het commando is mislukt.

Wat is Shell Expansion?

Wanneer u een extern commando uitvoert met system krijgt u het “shell expansion” effect.

Shell expansion is wanneer de shell (sh/bash/zsh) een aantal speciale tekens (*, ?, en ")# "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 of de Kernel#` methode.

Ze doen hetzelfde.

Hier is een voorbeeld:

`ls`

Een ander met %x:

%x|ls|

Deze twee voorbeelden geven een string terug met de uitvoer van het ls commando.

Merk op dat u nog steeds moet wachten tot het commando klaar is, tenzij u het binnen een thread uitvoert.

Hoe gebruik je Fork + Exec om externe opdrachten op een apart proces uit te voeren

Forking maakt een kopie van je huidige proces (je Ruby-applicatie), waarna je die kopie kunt vervangen door een ander proces met exec.

Opmerking: de fork-methode is niet beschikbaar onder Windows.

Dit is een populair patroon in de Unix-wereld.

Hier ziet u hoe het werkt:

fork { exec("ls") }

Dit zal ls op een ander proces & uitvoeren.

Omdat dit commando in een ander proces wordt uitgevoerd, zal het uw Ruby-app niet blokkeren zoals de system-methode of %x.

Belangrijk:

Als u exec gebruikt zonder fork gaat u uw huidige proces vervangen.

Dit betekent dat uw Ruby programma zal eindigen.

Hoe gebruik je de Popen Methode Voor Twee-Weg Communicatie Met Een Extern Programma

Als je:

  • Meer controle over het proces
  • Twee-Weg Communicatie

Dan is de IO.popen methode wat je zoekt.

In het volgende voorbeeld gebruik ik de popen methode om een irb proces te starten, dan wat invoer er naar toe te sturen & de uitvoer te lezen.

Hier het voorbeeld:

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

Deze r variabele is een IO object, dit betekent dat je er & van kunt lezen als een gewoon bestand.

Het gebruik van popen betekent ook dat uw externe commando op zijn eigen proces wordt uitgevoerd, zodat u het niet op een thread hoeft uit te voeren.

Er is ook een popen3 methode in de standaardbibliotheek.

Het verschil met de reguliere popen is dat het reguliere uitvoer & foutmeldingen zal splitsen in afzonderlijke IO-objecten.

Conclusie

U heeft geleerd over de verschillende manieren waarop u kunt communiceren met externe commando's in Ruby.

Ben hier voorzichtig mee!

Geef geen gebruikersinvoer door in deze commando's tenzij u een beveiligingsprobleem in uw Ruby app wilt.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.