为什么 bash -n 和 -z 测试运算符不为 $@ 取反
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15206840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are the bash -n and -z test operators not inverses for $@
提问by Mike Samuel
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
produces
产生
$*='' $@='' $@='' $@='' ![ -n $* ] [ -z $* ] [ -n $@ ] [ -z $@ ]
$*='' $@='' $@='' $@='' ![ -n $* ] [ -z $* ] [ -n $@ ] [ -z $@ ]
though it seems to me that [-n $@]should be false because 7.3 Other Comparison Operatorsindicates that [ -n "$X" ]should be the inverse of [ -z "$X" ]for all $X.
尽管在我看来这[-n $@]应该是错误的,因为7.3 Other Comparison Operators表明[ -n "$X" ]应该是[ -z "$X" ]for all的倒数$X。
-zstring is null, that is, has zero length
String='' # Zero-length ("null") string variable. if [ -z "$String" ] then echo "$String is null." else echo "$String is NOT null." fi # $String is null.
-nstring is not null.
The
-ntest requires that the string be quoted within the test brackets. Using an unquoted string with! -z, or even just the unquoted string alone within test brackets (see Example 7-6) normally works, however, this is an unsafe practice. Always quote a tested string. [1]
-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]
I know $@is special but I did not know it was special enough to violate boolean negation. What is happening here?
我知道它$@很特别,但我不知道它特别到足以违反布尔否定。这里发生了什么?
$ bash -version | head -1
GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.0)
The actual numeric exit codes are all 1or 0as per
实际的数字退出代码全部1或0按照
$ [ -n "$@" ]; echo "$?"
0
回答by chepner
When $@is empty, "$@"doesn't expand to an empty string; it is removed altogether. So your test is not
如果$@是空的,"$@"没有扩展到空字符串; 它被完全删除。所以你的测试不是
[ -n "" ]
but rather
反而
[ -n ]
Now -nisn't an operator, but just a non-empty string, which always tests as true.
Now-n不是运算符,而只是一个非空字符串,它总是测试为真。
回答by Aaron Digulla
"$@"doesn't do what you expect. It's not a different form of "$*", it expands to the quoted list of arguments passed to the current script.
"$@"不会做你期望的。它不是 的不同形式"$*",它扩展为传递给当前脚本的带引号的参数列表。
If there are no arguments, it expands to nothing. If there are two arguments aand b c, then it expands to "a" "b c"(i.e. it preserves whitespace in arguments) while "$*"expands to "a b c"and $*would expand to a b c(three words).
如果没有参数,它会扩展为空。如果有两个参数aand b c,那么它扩展到"a" "b c"(即它保留参数中的空格)同时"$*"扩展到"a b c"并且$*将扩展到a b c(三个单词)。

