2013-03-04 83 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 

產生

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

雖然在我看來,[-n [email protected]]應該是假的,因爲7.3 Other Comparison Operators表明[ -n "$X" ]應對所有的$X來說都是[ -z "$X" ]的倒數。

-z

字符串爲空,即,具有零長度

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

串不爲空。

-n測試要求在測試括號內引用該字符串。但是,使用帶引號的字符串! -z,或者甚至僅僅在測試括號內僅引用未加引號的字符串(請參見示例7-6)通常有效,但這是不安全的做法。總是引用測試過的字符串。 [1]

我知道[email protected]是特殊的,但我不知道它是特殊的,足以違反布爾否定。這裏發生了什麼?


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

實際數字退出代碼都是10按照

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

回答

7

[email protected]是空的,"[email protected]"不會膨脹到一個空字符串;它被完全刪除。所以,你的測試是不是

[ -n "" ] 

而是

[ -n ] 

現在-n不是一個運營商,而只是一個非空字符串,它總是測試爲真。

+0

好的。所以'$ @'是一些詞彙語法糖,它明顯地觸發了「-n'測試要求字符串被引用」警告。 – 2013-03-04 17:07:49

+6

這就是爲什麼我堅持'[['在bash中。 – choroba 2013-03-04 17:07:49

+0

@choroba:我只是驗證'[[...]]'很聰明,看到'-n'缺少它的參數。 – chepner 2013-03-04 17:08:59

1

"[email protected]"不符合您的期望。它不是"$*"的不同形式,它擴展爲傳遞給當前腳本的參數的引用列表。

如果沒有參數,則它展開爲空。如果存在兩個參數ab c,則它擴展到"a" "b c"(即它保留參數中的空白),而"$*"擴展到"a b c"並且$*將擴展到a b c(三個詞)。