bash条件表达式中_string_和-n _string_之间有什么区别?

时间:2013-09-15 06:02:36

标签: bash

Bash参考手册表示

  

[ string ]

  

[-n string ]

如果字符串的长度不为0,

将返回 true

但事实并非如此

greet=

if [ $greet ]; then
    echo '1'
else 
    echo '2'
fi

if [ -n $greet ]; then
    echo '1'
else
    echo '2'
fi

输出为
2
1

Bash参考手册只是说

-n string  
string  

True if the length of string is non-zero.  
那么,这两种形式之间真正的区别是什么?

3 个答案:

答案 0 :(得分:4)

正如@ user1502952所说,你需要使用双引号;但是让我解释为什么。假设您执行:

greet=
[ -n $greet ] && echo "it's nonblank"

当shell解析[ -n $greet ]部分时,它会将$greet扩展为空字符串,然后进行单词拆分。例如,如果$greet扩展为中间带空格的东西,它会将每个“单词”视为[命令的单独参数。但是,在这种情况下,$greet扩展为空,它根本不包含“单词”,因此被视为[的零参数 - 它实际上从命令中消失。因此[ -n $greet ]相当于[ -n ]会检查字符串“-n”是否为非空白。它是,所以评估为真。

将此与[ -n "$greet" ]进行比较:在这种情况下,双引号允许扩展$greet,但会阻止分词。因此[命令实际上获得了一个零长度的第二个参数,意识到-n应该是一个运算符,并获得预期的答案。

答案 1 :(得分:1)

当您使用-n选项时,需要使用双引号。

 if [ -n "$greet" ]

当字符串为空时,上面的表达式求值为false,因为长度为零。

 if [ "$greet" ] 

当字符串为空时,这也会计算为false。

此外,为了检查空字符串,可以使用-z选项。

if [ -z "$greet" ] 

这将是真的,因为字符串是空的。

也请检查此链接:http://tldp.org/LDP/abs/html/comparison-ops.html

答案 2 :(得分:0)

Bash在[内执行分词,但不在[[内执行分词,因此如果您使用[[,则不必引用参数:

$ x=
$ [ -n $x ]; echo $?; [ -n "$x" ]; echo $?
0
1
$ [[ -n $x ]]; echo $?; [[ -n "$x" ]]; echo $?
1
1

type[[ $x ]]显示为[[ -n $x ]]

$ f() { [[ $x ]]; }; type f
f is a function
f ()
{
    [[ -n $x ]]
}