Feb 222012
 

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:

Flattr this!

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*