前言

在写shell的时候发现一个违反直觉的的操作,一般判断一个变量是否为boolean,习惯上使用if param
但是在写脚本的时候,发现无论如何,不会走false。

反例

在很多编程语言中,可以直接使用 if boolean,来判断这个变量是否为true。但是在shell当中直觉上是可以,但实际上是不能。

1
2
3
4
5
6
aaa=false
if [[ $aaa ]];then
echo "is true"
else
echo "is false"
fi

结是为is true,是不是违反直觉。

为什么这段脚本会进is true

shell 是怎么执行这一段脚本的:

1
sh -x test.sh

结果:

1
2
3
4
+ aaa=false
+ [[ -n false ]]
+ echo 'is true'
is true

可以看到,如果是一个变量,shell 会默认加上-n来判断变量是否为空。aaa是有值的,而且在shell里,false 并不代表false。真正代表true和false的是01,没想到吧。

正常判断

注意,这里用的是=,而不是==,也是违反直觉,很多编程语言都是使用的==

1
2
3
4
5
6
aaa=false
if [ $aaa = true ];then
echo "is true"
else
echo "is false"
fi

在中括号[ ]中使用==是bash里的做法, 不符合posix标准。
posix,是通用操作系统接口的缩写。

Do not use ==. It is only valid in a limited set of shells, and will produce unspecified behavior.

尽量使用 = 而不是 ==

在shell当中==的作用是完全匹配。但是在不同的shell当中表现不同。我没有一个一个试,在查这个问题的时候,看到这段结论:

不支持的shell

dash:
4: [: A: unexpected operator
not support ==
tcsh:
test: unknown operator ==

支持的shell

bash:
support ==
ksh:
support ==

引用:http://stackoverflow.com/questions/10849297/compare-a-string-in-unix