Qual è la differenza tra i seguenti metodi di Ruby?
exec, systemE %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, systemE %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 systemmetodo 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, STDOUTe STDERRgli oggetti del vostro programma Ruby. Infatti, il valore restituito effettivo è o true, falseo nil. Nell'esempio la data è stata stampata attraverso l'oggetto IO di STDIN. Il metodo restituirà truese il processo è terminato con uno stato zero, falsese il processo è terminato con uno stato diverso da zero e nilse l'esecuzione non è riuscita.
Un altro effetto collaterale è che la variabile globale $?è impostata su un Process::Statusoggetto. 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 %we %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 %xpossono usare l'interpolazione di stringhe.
exec
Utilizzando Kernel#execil 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.popen3utile:
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.popen3invece; ad esempio, vedere stackoverflow.com/a/10922097/258662
Ecco un diagramma di flusso basato su questa risposta . Vedi anche, usando scriptper emulare un terminale .
Fanno cose diverse. execsostituisce il processo corrente con il nuovo processo e non ritorna mai . systeminvoca 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.