为什么bash -n和-z测试运算符不能反转$ @

时间:2013-03-04 16:59:18

标签: bash operators

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 Other Comparison Operators表示[ -n "$X" ]应该是所有[ -z "$X" ] $X的倒数。

  

-z

     

string为null,即长度为零

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

     

string不为空。

     

-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

2 个答案:

答案 0 :(得分:12)

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

[ -n "" ]

而是

[ -n ]

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

答案 1 :(得分:3)

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

如果没有参数,它会扩展为空。如果有两个参数ab c,那么它会扩展为"a" "b c"(即它会保留参数中的空格),而"$*"会扩展为"a b c"和{{ 1}}会扩展为$*(三个字)。