2013-03-04 6 views
5
function wtf() { 
    echo "\$*='$*'" 
    echo "\[email protected]='[email protected]'" 
    echo "\[email protected]='"[email protected]"'" 
    echo "\[email protected]='""[email protected]""'" 
    if [ -n "$*" ]; then echo " [ -n \$* ]"; else echo "![ -n \$* ]"; fi 
    if [ -z "$*" ]; then echo " [ -z \$* ]"; else echo "![ -z \$* ]"; fi 
    if [ -n "[email protected]" ]; then echo " [ -n \[email protected] ]"; else echo "![ -n \[email protected] ]"; fi 
    if [ -z "[email protected]" ]; then echo " [ -z \[email protected] ]"; else echo "![ -z \[email protected] ]"; fi 
} 

wtf 

produce

$*='' 
[email protected]='' 
[email protected]='' 
[email protected]='' 
![ -n $* ] 
[ -z $* ] 
[ -n [email protected] ] 
[ -z [email protected] ] 

anche se sembra a me che [-n [email protected]] dovrebbe essere falso perché 7.3 Other Comparison Operators indica che [ -n "$X" ] dovrebbe essere l'inverso di [ -z "$X" ] per tutti $X.

-z

stringa è nulla, cioè, ha una lunghezza pari a zero

String='' # Zero-length ("null") string variable. 

if [ -z "$String" ] 
then 
    echo "\$String is null." 
else 
    echo "\$String is NOT null." 
fi  # $String is null. 

-n

stringa non è nullo.

Il test -n richiede che la stringa venga quotata all'interno delle parentesi di prova. L'utilizzo di una stringa senza virgolette con ! -z, o anche solo la stringa non quotata tra parentesi quadre (vedi Esempio 7-6) normalmente funziona, tuttavia, questa è una pratica non sicura. Citare sempre una stringa testata. [1]

So [email protected] è speciale, ma non sapevo che fosse abbastanza speciale di violare negazione booleana. Cosa sta succedendo qui?


$ bash -version | head -1 
GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.0) 

L'attuale codici di uscita numerici sono tutti 1 o 0 secondo

$ [ -n "[email protected]" ]; echo "$?" 
0 

risposta

7

Quando [email protected] è vuota, "[email protected]" non si espande ad una stringa vuota; è rimosso del tutto. Quindi il test non è

[ -n "" ] 

ma piuttosto

[ -n ] 

Ora -n non è un operatore, ma solo una stringa non vuota, che verifica sempre come vero.

+0

Ok. Quindi '$ @' è un po 'di zucchero sintattico lessicale che non innesca ovviamente il "Il test' -n' richiede che la stringa sia quotata "avvertenza". –

+6

Ecco perché mi atteno a '[[' in bash. – choroba

+0

@choroba: stavo solo verificando che '[[...]] 'è abbastanza intelligente da vedere che' -n' manca il suo argomento. – chepner

1

"[email protected]" non fa quello che ti aspetti. Non è una forma diversa di "$*", si espande nell'elenco quotato degli argomenti passati allo script corrente.

Se non ci sono argomenti, si espande a nulla. Se ci sono due argomenti a e b c, poi si espande per "a" "b c" (cioè conserva spazi in argomenti) mentre "$*" espande per "a b c" e $* si espanderebbe a a b c (tre parole).