实例中除非特别标注,否则都不是在centos中测试的。
多数情况下[]和[[]]是可以通用的,两者的主要差异是:test或[]是符合POSIX标准的测试语句,兼容性更强,几乎可以运行在所有Shell解释器中,相比较而言[[]]仅可运行在特定的几个Shell解释器中(如Bash、Zsh等)。事实上,目前支持使用[[]]进行条件测试的解释器已经足够多了。使用[[]]进行测试判断时甚至可以使用正则表达式。
首先,测试两者的通用表达式(同样,一定要注意空格的问题,空格不可或缺)。
- csdn@ubuntu:~$ [[ 5 -eq 5 ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ -r main.c ]] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ -r other.c ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ 5 -eq 5 ] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ -r main.c ] && echo Y || echo N
- N
- csdn@ubuntu:~$ [ -r other.c ] && echo Y || echo N
- Y
- csdn@ubuntu:~$
看两者的差异点。其中,在[[]]中使用<和>符号时,系统进行的是排序操作,而且支持在测试表达式内使用&&和||符号。在test或[]测试语句中不可以使用&&和||符号。
注意
[[ ]]中的表达式如果使用<或>进行排序比较,使用的是本地的locale语言顺序。可以使用LANG=C设置在排序时使用标准的ASCII码顺序。
在ASCII码的顺序中,小写字母顺序码>大写字母顺序码>数字顺序码。
我的系统默认LANG值是zh_CN.UTF-8,所说义[]和[[]]的排序结果是不同的。
- csdn@ubuntu:~$ echo $LANG
- zh_CN.UTF-8
- csdn@ubuntu:~$ [ a > A ] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ a > A ]] && echo Y || echo N
- N
- csdn@ubuntu:~$
修改LANG=C
- csdn@ubuntu:~$ LANG=C
- csdn@ubuntu:~$ [[ a > A ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ a > A ] && echo Y || echo N
- Y
- csdn@ubuntu:~$
虽然[]也支持同时进行多个条件的逻辑测试,但是在[]中需要使用-a和-o进行逻辑与和逻辑或的比较操作,而[[]]中可以直接使用&&和||进行逻辑比较操作,更直观,可读性更好。A && B或者A -a B,意思是仅当A和B两个条件测试都成功时,整体测试结果才为真。A || B或者A -o B,意思是只要A或B中的任意一个条件测试成功,则整体测试结果为真。
- csdn@ubuntu:~$ [ y == y -a n == n ] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ y == n -o n == n ] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ y == n -a n == n ] && echo Y || echo N
- N
- csdn@ubuntu:~$ [ y == n -o n == n ] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ y == n -o n == y ] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ y == n && n == y ]] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ y == y || n == y ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ y == y || n == y ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ y == n || n == y ]] && echo Y || echo N
- N
- csdn@ubuntu:~$
需要注意的还有==比较符,在[[]]中==是模式匹配,模式匹配允许使用通配符。例如,Bash常用的通配符有*、? 、[…]等。而==在test语句中仅代表字符串的精确比较,判断字符串是否一模一样。下面的例子,测试变量name的值是否以字母c开头,后面可以是任意长度的任意字符,测试结果为真。总是使用之前多测试吧,感觉不太靠谱的样子。
- csdn@ubuntu:~$ name=csdn
- csdn@ubuntu:~$ [[ $name == c* ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ $name == c... ]] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ $name == c* ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ $name == c[a-z]* ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ $name == c[a-z]{3} ]] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ $name == c[.]{3} ]] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ $name == c[.]{4} ]] && echo Y || echo N
- N
- csdn@ubuntu:~$
接着,测试变量name的值是否以字母d开头,后面可以是任意长度的任意字符,测试结果为假。
- csdn@ubuntu:~$ [[ $name == d* ]] && echo Y || echo N
- N
- csdn@ubuntu:~$
测试变量name的值是否是c和dn中间有任意单个字符?结果为真
- csdn@ubuntu:~$ [[ $name == c?dn ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$
测试字符a,是否是小写字母?结果为真。
- csdn@ubuntu:~$ [[ a == [a-z] ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$
同样是使用==进行比较操作,但在[]中系统进行的是字符串的比较操作,判断两个字符串是否绝对相同。
下面是在ubuntu中测试的,会报错的。
- csdn@ubuntu:~$ [ c == c ] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [ c == c* ] && echo Y || echo N
- bash: [: too many arguments
- N
- csdn@ubuntu:~$
下面的是在centOS7中测试的,不会报错:
- [lkmao@MiWiFi-R3600-srv root]$ [ c == c* ] && echo Y || echo N
- N
- [lkmao@MiWiFi-R3600-srv root]$ name=csdn
- [lkmao@MiWiFi-R3600-srv root]$ [ $name == c* ] && echo Y || echo N
- N
- [lkmao@MiWiFi-R3600-srv root]$
另外,在[[]]中还支持使用=~进行正则匹配,而在[]中则完全不支持正则匹配。对变量name的值进行正则匹配,判断name的值是否包含字母c。
- csdn@ubuntu:~$ [[ $name =~ c ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$
对变量name的值进行正则匹配,判断name的值是否包含数字。
- csdn@ubuntu:~$ [[ $name =~ [0-9] ]] && echo Y || echo N
- N
- csdn@ubuntu:~$
对变量name的值进行正则匹配,判断name的值是否包含小写和大写字母。
- csdn@ubuntu:~$ [[ $name =~ [a-z] ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ name=Csdn
- csdn@ubuntu:~$ [[ $name =~ [a-z] ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ $name =~ [A-Z] ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$
最后,看看分组测试。使用()进行分组,效果类似于虽然在数学上默认先算乘除法再算加减法,但使用()后可以先算加减法再算乘除法。
下面这条命令,在a==a为真的情况下,b==b和c==d两个测试中只要有一个测试为真,则整体测试为真。多测几个值总是好的。测试原理中分条件测试、分支测试、路径测试。总之要测全,搞不好,你正在用的shell就不兼容某种用法。
- csdn@ubuntu:~$ [[ a == a ]] && echo Y || echo n
- Y
- csdn@ubuntu:~$ [[ a == a ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ a == a && (b == b) ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ a == a && ((b == b) && (c == c)) ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$ [[ a == a && ((b == b) && (c == d)) ]] && echo Y || echo N
- N
- csdn@ubuntu:~$ [[ a == a && ((b == b) || (c == d)) ]] && echo Y || echo N
- Y
- csdn@ubuntu:~$
终于学到尾声了。快吐了。
列出了[[]]和[]的差异汇总信息,相同点这里不再赘述。为了熟练掌握这些语法,本书后面的案例中将混合应用多种不同的条件测试语句。