E’ divertente come attraverso piccoli compiti quotidiani capiti di trovare nuove funzionalità o comandi che prima non si conoscevano, ed anche oggi mi è capitata questa cosa.
In particolare dovevo fare una cosa abbastanza semplice su un server dove avevo un terminale, lanciare : comando1 | tail -n 2
tail
mi serviva per avere da un lungo output solo le linee significative che poi dovevo passare ad un’altra funzione, ma oltre a questo mi serviva capire anche che il comando1 fosse terminato con un exit code 0 o nel caso non lo fosse con quale codice di uscita era terminato.
Un semplice :
.... comando1 | tail -n 2 if [ $? -ne 0 ] then echo "comando1 fallito." EXIT_CODE=1 fi .... |
Non funziona in quanto prende sempre il codice di uscita di tail
, che nel mio caso è sempre 0.
Ho quindi googlato un po ed ho trovato più di una soluzione per questo semplice problema.
Ok, cominciamo con la soluzione che ho usato, in bash:
1) Se avete cmd1 | cmd2 | cmd3
In Bash i codici di uscita sono posizionati nel’array speciale PIPESTATUS. Il codice di uscita di cmd1 è in ${PIPESTATUS[0]}, il codice di uscita di cmd3 in ${PIPESTATUS[2]}, ed infine $? è sempre contenuto in ${PIPESTATUS: -1}. Ma è davvero così semplice?
Sì, una volta che si conosce questa funzione , ottenere il giusto codice di uscita è banale!
Quindi il mio codice è diventato:
comando1 | tail-n 2
if [ ${PIPESTATUS[0]} -ne 0]
then
echo “comando1 fallito.”
EXIT_CODE = 1
fi
2) Potete usare una soluzione simile anche per zsh Anche in questa schell i codici di uscita sono forniti nell’array speciale pipestatus . cmd1 exit code è in $pipestatus[1], cmd3 exit code in $pipestatus[3], e $? è sempre contenuto in $pipestatus[-1].
Quindi, come potete vedere questa è esattamente la stessa soluzione utilizzata in bash.
3) Per Ksh e, probabilmente, altre shell in stile bash, è necessario utilizzare un trucco per passare i codici di uscita alla shell principale. Potete farlo utilizzando una pipe(2). Invece di lanciare “cmd1”, si esegue “cmd1; echo $?” e ci si assicura che $? prenda la strada corretta per la shell.
Questo è l’esempio più complesso, e suggerisco di dare un’occhiata al reindirizzamento I/O in Unix/Linux se avete qualche dubbio.
#! /usr/bin/ksh exec 4>&1 tail -n 2 >&4 |& exec >&p command1 exitcode=$? exec >&- >&4 wait if [ ${exitcode} -ne 0] then echo "command1 failed." EXIT_CODE = 1 fi |
Quindi in conclusione, fortunatamente per me in bash esiste quello speciale array !
E moltissimi ringraziamenti al forum unix.com per le molte utili informazioni presenti.
Popular Posts:
- None Found