15
function wtf() {
  echo "\$*='$*'"
  echo "\$@='$@'"
  echo "\$@='"$@"'"
  echo "\$@='""$@""'"
  if [ -n "$*" ]; then echo " [ -n \$* ]"; else echo "![ -n \$* ]"; fi
  if [ -z "$*" ]; then echo " [ -z \$* ]"; else echo "![ -z \$* ]"; fi
  if [ -n "$@" ]; then echo " [ -n \$@ ]"; else echo "![ -n \$@ ]"; fi
  if [ -z "$@" ]; then echo " [ -z \$@ ]"; else echo "![ -z \$@ ]"; fi
}

wtf

生产

$*=''
$@=''
$@=''
$@=''
![ -n $* ]
 [ -z $* ]
 [ -n $@ ]
 [ -z $@ ]

尽管在我看来这[-n $@]应该是错误的,因为7.3 其他比较运算符表明[ -n "$X" ]应该是[ -z "$X" ]for all的倒数$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]

我知道$@它很特别,但我不知道它特别到足以违反布尔否定。这里发生了什么?


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

实际的数字退出代码是全部10按照

$ [ -n "$@" ]; echo "$?"
0
4

2 回答 2

18

$@为空时,"$@"不展开为空字符串;它被完全删除。所以你的测试不是

[ -n "" ]

反而

[ -n ]

Now-n不是一个运算符,而只是一个非空字符串,它总是测试为真。

于 2013-03-04T17:05:47.990 回答
3

"$@"不符合您的预期。它不是 的不同形式"$*",它扩展为传递给当前脚本的引用参数列表。

如果没有参数,它会扩展为空。如果有两个参数aand b c,那么它扩展为"a" "b c"(即它保留参数中的空格),同时"$*"扩展为"a b c"and$*将扩展为a b c(三个单词)。

于 2013-03-05T08:22:26.860 回答