In uno script rubino, ci sono various ways chiamare comandi di sistema/righe di comandoCome far fallire lo script Ruby quando il comando shelled-out restituisce un codice di uscita diverso da zero?
- backticks:
`command arg1 arg2`
- forma delimitato, ad esempio
%x(command arg1 arg2)
(altri delimitatori disponibili) Kernel#system
metodo:system('command arg1 arg2')
Kernel#exec
metodo:exec('command arg1 arg2')
Se voglio lo script di Ruby a fallire (con un'eccezione) quando un comando chiamato fallisce (con un non-zero codice di uscita) posso o controllare il codice di uscita nella variabile speciale $?
per i primi due varianti:
`command arg1 arg2`
fail unless $? == 0
o
%x,command arg1 arg2,
fail unless $? == 0
Se sto bene con lo standard output del comando andando a standard output dello script di Ruby (e sono), posso usare la variante 3 e controllare il suo valore di ritorno:
unless system('command arg1 arg2')
fail
end
Se io non mi interessa la possibilità di salvare l'eccezione né il comportamento di stampa stacktrace di eccezioni non ridotte, posso ovviamente usare exit(1)
o nelle prime due varianti exit($?)
al posto di fail
.
Se ulteriormente l'esecuzione del comando è l'ultima cosa che lo script di Ruby dovrebbe fare, anche quando il comando ha esito positivo (codice di uscita 0
), posso usare la quarta variante:
exec('command arg1 arg2')
Questo sostituirà la Processo di Ruby con il nuovo processo creato invocando il comando, ma l'effetto per il chiamante dello script Ruby sarà lo stesso: Verrà visualizzato un codice di uscita diverso da zero esattamente se il comando chiamato ha causato un codice di uscita diverso da zero.
Mi piace molto la concisione della quarta variante, ma se eseguire il comando non è l'ultima cosa da fare in caso di esito positivo, purtroppo non lo uso. Le invocazioni condizionali fail
o exit
delle altre varianti appaiono molto impure in confronto e in un caso precedente il mio non violano il singolo livello di astrazione e principi di responsabilità singola.
Potrei ovviamente scrivere facilmente una funzione wrapper per uno dei primi tre approcci per rendere il loro uso un aspetto altrettanto conciso, ma poiché sembra un modus operandi così fondamentale, Mi chiedevo se Ruby abbia già qualcosa del genere costruito in ... sia una funzione di utilità che potrei usare al posto di un wrapper o un meccanismo che modifica il comportamento di uno o più metodi di chiamata di comando per causare un errore o un'uscita diversa da zero quando un comando fallito, analogo a sh e option to set -e
option to set -e
.
Bello. Poiché [i backquote usano 'Kernel # \' '] (http://ruby-doc.com/docs/ProgrammingRuby/html/tut_expressions.html#UB), immagino che questo approccio possa funzionare anche per loro. –
Wow, non sapevo che fosse in realtà un metodo! Sì, sembra funzionare bene se si sostituisce ': \' 'per': system' – Max