首先要清楚的是在shell中[]和[[]]都是命令,和我们熟悉的ls、cd地位一样shell把它们都认做命令,就是说在命令输入[]和[[]]是不会报错(输入时[]和[[]]中间要空格哦),并且有命令返回状态码的。
在shell手册中,[]出现在內建命令章节,[[]]出现在条件结构章节。
http://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-Shell-Builtins
http://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html#Conditional-Constructs
下面简单说下它们的异同。
相同点:主要应用场景都是用来执行条件表达式的判断。
不同点:
1.在[[ ]]中不会进行word splitting和filename expansion,而在[ ]中会进行。
word splitting和filename expansion是shell的两个特性,直译就是分词和文件名展开,分词一般在参数展开后进行,分词即将一个单元分解成几个单元,文件名展开即将星号展开为当前工作目录下所有的文件。
当变量a为空时,[ -n $a ]和[ -z $a ]都会返回0,这不是我们期望的结果,原因在于进行参数展开($a)后,会进行word splitting,而a为空,word splitting会移除空值,所以[ -n $a ]和[ -z $a ]实际是执行[ -n ]和[ -z ],而[ ]中仅一个参数时且非空都是返回0的,所以 使用[ ]进行条件判断时,最好加上引号
2.[[ ]]中使用==,!=,~=时可以进行正则匹配
buddy@buddy-PC:~$ a="1 2" buddy@buddy-PC:~$ [ -n $a ] bash: [: 1: 需要二元表达式 buddy@buddy-PC:~$ [[ -n $a ]] buddy@buddy-PC:~$ [ -n "$a" ] buddy@buddy-PC:~$ a= buddy@buddy-PC:~$ buddy@buddy-PC:~$ [ -n $a ] buddy@buddy-PC:~$ echo $? 0 buddy@buddy-PC:~$ [ -z $a ] buddy@buddy-PC:~$ echo $? 0 buddy@buddy-PC:~$ [[ -n $a ]] buddy@buddy-PC:~$ echo $? 1 buddy@buddy-PC:~$ [[ -z $a ]] buddy@buddy-PC:~$ echo $? 0 buddy@buddy-PC:~$
buddy@buddy-PC:~$ [[ -n ]]
bash: 一元条件运算符使用了未预期的参数 `]]'
bash: `]]' 附近有语法错误
buddy@buddy-PC:~$