Qual è la differenza tra i seguenti metodi di Ruby?
exec
, system
E %x()
o backtick
So che vengono utilizzati per eseguire i comandi di terminale a livello di codice tramite Ruby, ma mi piacerebbe sapere perché ci sono tre modi diversi per farlo.
Qual è la differenza tra i seguenti metodi di Ruby?
exec
, system
E %x()
o backtick
So che vengono utilizzati per eseguire i comandi di terminale a livello di codice tramite Ruby, ma mi piacerebbe sapere perché ci sono tre modi diversi per farlo.
Risposte:
sistema
Il system
metodo chiama un programma di sistema. Devi fornire il comando come argomento stringa a questo metodo. Per esempio:
>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
Il programma richiamato userà la corrente STDIN
, STDOUT
e STDERR
gli oggetti del vostro programma Ruby. Infatti, il valore restituito effettivo è o true
, false
o nil
. Nell'esempio la data è stata stampata attraverso l'oggetto IO di STDIN
. Il metodo restituirà true
se il processo è terminato con uno stato zero, false
se il processo è terminato con uno stato diverso da zero e nil
se l'esecuzione non è riuscita.
Un altro effetto collaterale è che la variabile globale $?
è impostata su un Process::Status
oggetto. Questo oggetto conterrà informazioni sulla chiamata stessa, incluso l'identificatore del processo (PID) del processo richiamato e lo stato di uscita.
>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>
apici inversi
Backticks (``) chiama un programma di sistema e ne restituisce l'output. A differenza del primo approccio, il comando non viene fornito tramite una stringa, ma inserendolo in una coppia di backtick.
>> `date`
=> Wed Sep 4 22:22:51 CEST 2013
Anche la variabile globale $?
viene impostata attraverso i backtick. Con i backtick puoi anche usare l'interpolazione di stringhe.
%X()
L'utilizzo %x
è un'alternativa allo stile di backtick. Restituirà anche l'output. Come i suoi parenti %w
e %q
(tra gli altri), qualsiasi delimitatore sarà sufficiente finché i delimitatori in stile parentesi corrispondono. Questo mezzo %x(date)
, %x{date}
e %x-date-
sono tutti sinonimi. Come i backtick %x
possono usare l'interpolazione di stringhe.
exec
Utilizzando Kernel#exec
il processo corrente (il tuo script Ruby) viene sostituito con il processo richiamato exec
. Il metodo può prendere una stringa come argomento. In questo caso la stringa sarà soggetta all'espansione della shell. Quando si utilizza più di un argomento, il primo viene utilizzato per eseguire un programma e vengono forniti come argomenti al programma da invocare.
Open3.popen3
A volte le informazioni richieste vengono scritte nell'input standard o nell'errore standard ed è necessario avere il controllo anche su quelle. Ecco Open3.popen3
utile:
require 'open3'
Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
pid = thread.pid
puts stdout.read.chomp
end
STDIN
, STDOUT
, STDERR
, considerano Open3.popen3
invece; ad esempio, vedere stackoverflow.com/a/10922097/258662
Ecco un diagramma di flusso basato su questa risposta . Vedi anche, usando script
per emulare un terminale .
Fanno cose diverse. exec
sostituisce il processo corrente con il nuovo processo e non ritorna mai . system
invoca un altro processo e restituisce il valore di uscita al processo corrente. L'uso dei backtick invoca un altro processo e restituisce l'output di quel processo al processo corrente.