2010-09-03 12 views
17

Ho bisogno di catturare l'output e l'errore di un comando nel mio script bash e sapere se il comando è riuscito o meno.bash cattura variabile stderr e stdout separatamente o ottiene il valore di uscita

Al momento, sto catturando sia così:

output=$(mycommand 2>&1) 

Poi ho bisogno di controllare il valore di uscita di myCommand. Se non funziona, ho bisogno di fare qualcosa con l'output, se il comando è riuscito, non ho bisogno di toccare l'output.

Dal momento che sto acquisendo l'output, controllando $? è sempre uno 0 da quando bash è riuscito a catturare l'output nella variabile.

Questo è un molto tempo sceneggiatura sensibile, quindi stiamo cercando di evitare eventuali soluzioni più lenti come l'output in un file e ri-lettura in.

Se potessi catturare stdout ad una variabile e stderr ad un altro, questo risolverebbe il mio problema perché potrei controllare se la variabile di errore fosse vuota o meno.

Grazie.

+4

Sede [BashFAQ/002] (http://mywiki.wooledge.org/BashFAQ/002) e [BashFAQ/047] (http://mywiki.wooledge.org/BashFAQ/047). –

risposta

8

Quale versione di bash stai utilizzando? La cattura del uscita ha a zero effetto sul codice di ritorno con la mia versione, 4.1.5:

pax> false; echo $? 
1 
pax> echo $? 
0 
pax> x=$(false 2>&1) ; echo $? 
1 

Non è sempre una buona idea fare affidamento su standard error essere non vuoto per rilevare gli errori. Molti programmi non emettono errori ma si basano su unicamente sul codice di ritorno.

+0

Ho dimenticato di dire che ho collegato l'output del mio comando a un altro. Anche se posso farlo dopo reparti in un comando separato. Grazie. – mhost

+3

Attenzione! Avendo 'local x = $ (false 2> &1) ; echo $?' O 'set x = $ (false 2> &1) ; echo $?' (Nota ** 'local/set' ** all'inizio) output' 0' non '1' come l'ultima esecuzione del comando è' local/set'. –

10

Il problema sembra solo per manifestare quando l'uscita viene catturato ad un variabile locale all'interno di una funzione:

$ echo $BASH_VERSION 
3.2.48(1)-release 
$ false; echo $? 
1 
$ echo $? 
0 
$ x=$(false 2>&1) ; echo $? 
1 
$ function f { 
> local x=$(false 2>&1) ; echo $? 
> } 
$ f 
0 
$ function g { 
> x=$(false 2>&1) ; echo $? 
> } 
$ g 
1 

Avviso che solo funzione f, che cattura x ad un locale, può esprimere il comportamento. In particolare, la funzione g che fa la stessa cosa, ma senza la parola chiave 'local', funziona.

Uno non può quindi utilizzare una variabile locale e forse "disconnetterlo" dopo l'uso.

EDIT NVRAM sottolinea che la dichiarazione locale può essere fatta in anticipo per evitare il problema:

$ function h { 
> local x 
> x=$(false 2>&1) ; echo $? 
> } 
$ h 
1 
+0

Molto interessante! Questo succede in shell bash e dash (posix). – Gregor

+3

In realtà $? È impostato per la dichiarazione della variabile locale, se lo si dichiara semplicemente con da solo, _quando_ assegnalo su una linea separata funzionerà come vuoi.In altre parole, aggiungi ** local x ** sopra la tua linea con ** x = ** – NVRAM

Problemi correlati