Come eseguire comandi di sistema da Ruby

Se vuoi eseguire un comando esterno da Ruby…

…come wkhtmltopdf per convertire un file HTML in PDF.

Ci sono alcuni metodi Ruby che puoi usare.

A seconda del metodo che usi otterrai risultati diversi.

Esaminiamo insieme questi metodi!

Il metodo Ruby System

Il metodo Ruby system è il modo più semplice per eseguire un comando esterno.

Sembra questo:

system("ls")

Nota che system stamperà l’output del comando mentre avviene.

Anche il sistema farà aspettare il tuo programma Ruby fino a quando il comando non sarà terminato.

Prova questo:

system("sleep 2")

Ci sono modi per eseguire comandi in background come vedremo più avanti.

Il sistema può restituire 3 possibili valori:

  • true se il comando ha funzionato
  • false se il comando restituisce un codice di errore
  • nil se l’esecuzione del comando fallisce (comando non trovato)

È possibile ottenere il codice di stato di uscita dell’ultimo comando esterno eseguito con la variabile globale $?. Questo codice di stato può darti maggiori informazioni sul perché il comando è fallito.

Che cos’è l’espansione della shell?

Quando esegui un comando esterno con system avrai l’effetto “espansione della shell”.

L’espansione della shell è quando la shell (sh/bash/zsh) prende alcuni caratteri speciali (*, ?, e ")# "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 o il metodo Kernel#`.

Fanno la stessa cosa.

Ecco un esempio:

`ls`

Un altro con %x:

%x|ls|

Questi due esempi restituiranno una stringa con l'output del comando ls.

Come usare Fork + Exec per eseguire comandi esterni su un processo separato

Il fork crea una copia del tuo processo attuale (la tua applicazione Ruby) poi puoi sostituire quella copia con un altro processo usando exec.

Nota: Il metodo fork non è disponibile su Windows.

Questo è un modello popolare nel mondo Unix.

Ecco come funziona:

fork { exec("ls") }

Questo eseguirà ls su un altro processo & visualizzandone l'output.

Perché questo comando viene eseguito in un altro processo non bloccherà l'esecuzione della tua applicazione Ruby come il metodo system o %x.

Importante:

Se usi exec senza fork sostituirai il tuo processo attuale.

Questo significa che il tuo programma Ruby finirà.

Come usare il metodo Popen per la comunicazione bidirezionale con un programma esterno

Se hai bisogno di:

  • Maggiore controllo sul processo
  • Comunicazione bidirezionale

allora il metodo IO.popen è quello che stai cercando.

Nel seguente esempio uso il metodo popen per lanciare un processo irb, poi gli mando qualche input & e leggo l'output.

Ecco l'esempio:

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

Questa variabile r è un oggetto IO, ciò significa che puoi scrivere & leggere da essa come un normale file.

Utilizzare popen significa anche che il vostro comando esterno verrà eseguito sul proprio processo, quindi non dovete eseguirlo su un thread.

C'è anche un metodo popen3 nella libreria standard.

La differenza con il normale popen è che dividerà i normali messaggi di errore & di output in oggetti IO separati.

Conclusione

Hai imparato i diversi modi in cui puoi interagire con i comandi esterni in Ruby.

Stai attento con questi!

Non passare nessun tipo di input utente in questi comandi a meno che tu non voglia un problema di sicurezza nella tua applicazione Ruby.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.