How to Run System Commands From Ruby

Ha egy külső parancsot akarunk futtatni Rubyból…

…mint például a wkhtmltopdf egy HTML fájl PDF-be való konvertálásához.

Van néhány Ruby módszer, amit használhatunk.

Az alkalmazott módszertől függően különböző eredményeket kapunk.

Vizsgáljuk meg együtt ezeket a módszereket!

A Ruby rendszermódszer

A Ruby rendszermódszer a legegyszerűbb módja egy külső parancs futtatásának.

Ez így néz ki:

system("ls")

Megjegyezzük, hogy a system kiírja a parancs kimenetét, amint az történik.

A rendszer továbbá arra készteti a Ruby programodat, hogy várjon, amíg a parancs befejeződik.

Kipróbáld ezt:

system("sleep 2")

A parancsok háttérben történő futtatásának is vannak módjai, mint később látni fogjuk.

A rendszer 3 lehetséges értéket adhat vissza:

  • true ha a parancs működött
  • false ha a parancs hibakódot ad vissza
  • nil ha a parancs végrehajtása sikertelen (parancs nem található)

A $? globális változóval megkaphatjuk a legutóbb futtatott külső parancs exit status kódját. Ez az állapotkód további információt adhat arról, hogy a parancs miért sikertelen.

Mi az a Shell bővítés?

Ha egy külső parancsot futtatsz a system segítségével, akkor megkapod a “shell bővítés” hatást.

A shell bővítés az, amikor a shell (sh/bash/zsh) néhány speciális karaktert (*, ? és ")# "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 vagy a Kernel#` módszert.

Ezek ugyanazt teszik.

Itt egy példa:

`ls`

Egy másik a %x-val:

%x|ls|

Ez a két példa egy stringet ad vissza a ls parancs kimenetével.

Megjegyezzük, hogy még mindig várnunk kell a parancs befejezésére, hacsak nem egy szálon belül futtatjuk.

How to Use Fork + Exec To Run External Commands On a Separate Process

Forking készít egy másolatot az aktuális folyamatról (a Ruby alkalmazásról), majd ezt a másolatot egy másik folyamattal helyettesítheti az exec segítségével.

Megjegyzés: A fork módszer nem elérhető Windows alatt.

Ez egy népszerű minta a Unix világában.

Íme, hogyan működik:

fork { exec("ls") }

Ez a ls egy másik folyamat & kimenetének megjelenítésével

Mivel ez a parancs egy másik folyamatban fut, nem fogja blokkolni a Ruby alkalmazásod futását, mint a system módszer vagy a %x.

Fontos:

Ha a exec parancsot fork nélkül használod, akkor lecseréli az aktuális folyamatodat.

Ez azt jelenti, hogy a Ruby programod véget ér.

Hogyan használd a Popen módszert a kétirányú kommunikációhoz egy külső programmal

Ha szükséged van:

  • több kontrollra a folyamat felett
  • kétirányú kommunikációra

akkor a IO.popen módszer az, amit keresel.

A következő példában a popen metódussal elindítok egy irb folyamatot, majd küldök neki némi bemenetet & kiolvasom a kimenetet.

Itt a példa:

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

Ez a r változó egy IO objektum, ez azt jelenti, hogy írni & olvasni lehet róla, mint egy hagyományos fájlból.

A popen használata azt is jelenti, hogy a külső parancsod saját folyamatában fog futni, így nem kell egy szálon futtatnod.

A standard könyvtárban is van egy popen3 módszer.

A különbség a szokásos popen-hoz képest az, hogy a szokásos kimeneti & hibaüzeneteket külön IO objektumokra osztja.

Következtetés

Megtanultad, hogy milyen különböző módon léphetsz kapcsolatba külső parancsokkal a Ruby-ban.

Vigyázz ezekkel!

Ne adj át semmiféle felhasználói bemenetet ezekbe a parancsokba, hacsak nem akarsz biztonsági problémát a Ruby alkalmazásodban.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.