Jak spouštět systémové příkazy z Ruby

Pokud chcete spustit externí příkaz z Ruby…

…například wkhtmltopdf pro převod HTML souboru do PDF.

Existuje několik metod Ruby, které můžete použít.

V závislosti na použité metodě dostanete různé výsledky.

Prozkoumejme tyto metody společně!

Systémová metoda Ruby

Systémová metoda Ruby je nejjednodušší způsob, jak spustit externí příkaz.

Vypadá takto:

system("ls")

Všimněte si, že system vypíše výstup příkazu, jakmile se tak stane.

Také systém donutí váš program v Ruby čekat, dokud nebude příkaz dokončen.

Zkuste to takto:

system("sleep 2")

Jsou způsoby, jak spouštět příkazy na pozadí, jak uvidíme později.

Systém může vrátit 3 možné hodnoty:

  • true pokud příkaz fungoval
  • false pokud příkaz vrátí chybový kód
  • nil pokud se provedení příkazu nezdaří (příkaz nebyl nalezen)

Kód stavu ukončení posledního spuštěného externího příkazu můžete získat pomocí globální proměnné $?. Tento stavový kód vám může poskytnout více informací o tom, proč příkaz selhal.

Co je to expanze shellu?

Pokud spustíte externí příkaz pomocí system, získáte efekt „expanze shellu“.

Expanze shellu je, když shell (sh/bash/zsh) přijme některé speciální znaky (*, ? a ")# "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 nebo metodu Kernel#`.

Dělají totéž.

Tady je příklad:

`ls`

Další s %x:

%x|ls|

Tyto dva příklady vrátí řetězec s výstupem příkazu ls.

Všimněte si, že stále musíte čekat na dokončení příkazu, pokud jej nespustíte uvnitř vlákna.

Jak použít Fork + Exec ke spuštění externích příkazů v samostatném procesu

Forkováním se vytvoří kopie aktuálního procesu (aplikace Ruby), kterou pak můžete nahradit jiným procesem pomocí exec.

Poznámka: Metoda fork není k dispozici v systému Windows.

Jedná se o oblíbený vzor v unixovém světě.

Takto to funguje:

fork { exec("ls") }

Tento příkaz spustí ls na jiném procesu & zobrazí jeho výstup.

Protože tento příkaz běží v jiném procesu, nebude blokovat běh vaší aplikace Ruby jako metoda system nebo %x.

Důležité:

Použijete-li příkaz exec bez příkazu fork, nahradí váš aktuální proces.

To znamená, že váš program Ruby skončí.

Jak použít metodu Popen pro obousměrnou komunikaci s externím programem

Pokud potřebujete:

  • Větší kontrolu nad procesem
  • Obousměrnou komunikaci

Pak je metoda IO.popen to, co hledáte.

V následujícím příkladu pomocí metody popen spustím irb proces, pak mu pošlu nějaký vstup & přečtu výstup.

Tady je příklad:

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

Tato proměnná r je IO objekt, to znamená, že z ní můžete zapisovat & číst jako z běžného souboru.

Použití popen také znamená, že váš externí příkaz poběží ve vlastním procesu, takže ho nemusíte spouštět ve vlákně.

Ve standardní knihovně je také metoda popen3.

Rozdíl oproti běžné popen je v tom, že rozdělí běžné výstupní & chybové zprávy na samostatné IO objekty.

Závěr

Poznali jste různé způsoby interakce s externími příkazy v jazyce Ruby.

Dávejte si na ně pozor!

Nepředávejte do těchto příkazů žádný uživatelský vstup, pokud nechcete, aby ve vaší aplikaci Ruby vznikl problém se zabezpečením.

Předpokládám, že jste se naučili pracovat s externími příkazy.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.