2015-04-18 17 views
8

ero un po 'disturbato per trovare il seguente comportamento:

bash$ false 
bash$ true | echo $? 
0 
bash$ ksh 
ksh$ false 
ksh$ true | echo $? 
0 
ksh$ zsh 
zsh$ false 
zsh$ true | echo $? 
1 

Intuitivamente, sembra zsh ottiene di destra mentre bash e ksh sono sbagliate. $? è "lo stato di uscita della pipeline eseguita più recentemente", che in ogni caso dovrebbe essere 1. Nota che false | echo $? stampa anche 0 in entrambi ksh e bash. Lo standard è flessibile su questo punto (ad esempio, il comportamento non è specificato) oppure bash e ksh non conformi qui? Sono anche curioso di sapere cosa stanno facendo bash e ksh per sbagliare.

$ bash --version 
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11) 
Copyright (C) 2007 Free Software Foundation, Inc. 
$ zsh --version 
zsh 4.3.11 (i386-apple-darwin11.0) 
$ ksh --version 
    version   sh (AT&T Research) 1993-12-28 s+ 
+2

Quando ho eseguito l'esempio 'bash', ho ottenuto' 1', non '0'. – lurker

+0

Quale versione di bash? Produce lo stesso del tuo output zsh sul mio sistema. – Mat

+0

Si prega di citare la versione di shell per favore per tutti. Con me 'zsh' ha effettivamente restituito' 0'. Impossibile verificare quindi. –

risposta

4

POSIX dice:

$? espande per lo stato di uscita decimale del più recente [comando o] gasdotto ...

Si prega di notare il commento da @lurker. Bash nella sua versione attuale 4.3.11 si comporta come zsh.

Cosa accade in bash e zsh è che $? verranno impostati dal comando prima tubo e ottiene non cambiato all'interno del tubo. Ecco perché il risultato atteso è il valore di ritorno da false ->1. E questo è ciò che specifica POSIX.

Non sono riuscito a trovare alcuna documentazione che descriva il comportamento di ksh. Posso solo supporre che ksh azzera $? prima di eseguire il tubo, dal momento che il seguente codice funziona:

#!/bin/ksh 
false 
ret=$? 
true | echo "$ret" 

Probabilmente questo dovrebbe archiviato come un bug in ksh. Tuttavia, non sono sicuro che questo comportamento sia specificato esattamente da POSIX.

+2

Sì, quindi in ogni caso '$?' Dovrebbe essere lo stato restituito da 'false'. Dovrebbe fare riferimento alla pipeline più recente e la costruzione della pipeline in cui viene utilizzata dovrebbe essere irrilevante. –

+0

@ hek2mgl Huh? Come potrebbe '$?' In 'echo $?' Espandere allo stato di uscita di 'echo'? Viene valutato prima dell'esecuzione di 'echo'. Certo, * dopo *, 'echo' sarà impostato sullo stato di uscita di 'echo' (in genere zero), ma non è di questo che si tratta, vero? – hvd

+0

Sì, lo vedo ora. È stato stupido assumere "echo" .. – hek2mgl