关闭

替代test语句的[ ]和[[ ]]表达式有什么区别

415人阅读 评论(0) 收藏 举报
分类:
首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。
"[[",是关键字,许多shell(如ash bsh)并不支持这种方式。ksh, bash(据说从2.02起引入对[[的支持)等支持。
"["是一条命令, 与test等价,大多数shell都支持。在现代的大多数sh实现中,"["与"test"是内部(builtin)命令,换句话说执行"test"/"["时不会调用/some/path/to/test这样的外部命令(如果有这样的命令的话)。
下面是在rh7.3下的测试结果,GNU bash, version 2.05a.0(1),安装了sh-utils。
代码:
$ type test
test is a shell builtin
$ type [
[ is a shell builtin
$ rpm -ql sh-utils|grep test
/usr/bin/test
/usr/share/man/man1/test.1.gz
$ ls -l `which test`
-rwxr-xr-x    1 root     root        20424  4月  9  2002 /usr/bin/test
ls -l $(which [)
lrwxrwxrwx    1 root     root            4  8月 23  2002 /usr/bin/[ -> test

在你的机器上结果可能会有所不同哦。

2. 相同的地方是二者都支持算术比较和字符串比较表达式。

"-gt", "-lt"是算术比较操作符,用于比较整数的大小。

">", "<"是字符串比较操作符,用于比较字符串的大小,使用字典顺序,与当前的locale有关。

另外,"="还可以做简单的模式匹配,与一般的正则表达式不同,这里的模式匹配要简单得多,类似文件名的统配符的扩展规则。还要注意等号右端的模式不能用引号括起。

第2点是谈相同点,以下的都是二者"行为上"的不同点。

3. [[的行为相对地更接近于其他语言,例如"&&"而不是"-a"表示逻辑"与",用"||"而不是"-o"表示逻辑"或"。
例如:
代码:
$ [[ 1 < 2 && b > a ]]&&echo true||echo false
true
$ [[ 1 < 2 -a b > a ]]&&echo true||echo false
bash: syntax error in conditional expression
bash: syntax error near `-a'
$ [ 1 < 2 -a b > a ]&&echo true||echo false
true
$ [ 1 < 2 && b > a ]&&echo true||echo false  #wrong syntax
bash: [: missing `]'
false
$ [ 1 < 2 && b > a ]&&echo true||echo false  #aslo wrong
bash: [: &&: binary operator expected
false


4. [ ... ]为shell命令,所以在其中的表达式应是它的命令行参数,所以串比较操作符">" 与"<"必须转义,否则就变成IO改向操作符了(请参看上面2中的例子)。在[[中"<"与">"不需转义;
由于"[["是关键字,不会做命令行扩展,因而相对的语法就稍严格些。例如
在[ ... ]中可以用引号括起操作符,因为在做命令行扩展时会去掉这些引号,而在[[ ... ]]则不允许这样做。
举例:
代码:
$ [ "-z" "" ]&&echo true||echo false
true
$ [ -z "" ]&&echo true||echo false
true
$ [[ "-z" "" ]]&&echo true||echo false
bash: conditional binary operator expected
bash: syntax error near `""'
$ [[ -z "" ]]&&echo true||echo false
true



5. [[ ... ]]进行算术扩展,而[ ... ]不做。
举例:
代码:
$ [[ 99+1 -eq 100 ]]&&echo true||echo false
true
$ [ 99+1 -eq 100 ]&&echo true||echo false
bash: [: 99+1: integer expression expected
false
$ [ $((99+1)) -eq 100 ]&&echo true||echo false
true

数字的运算可使用let、(( )) ,其中运算时不需要变量$符号,运算符为 +、-、*、/、% ,不建议使用expr
数字的比较使用 (( )) ,其运算符 >、>=、<、<=、==、!=
可以使用算术扩展,如:(( 99+1 <= 101 ))
字符表达式的比较使用 [[ ]] ,其运算符 =、!=、-n、-z
文件表达式的测试使用 [[ ]] ,其运算符 -r、-l、-w、-x、-f、-d、-s、-nt、-ot
逻辑表达式的测试使用 [[ ]] ,其运算符 !、&&、||
数字比较、字符比较、逻辑测试可以组合,如$ [[ "a" != "b" && 4 -gt 3 ]]
支持bash中的通配符扩展,如:[[ hest = h??t ]] 、[ hest = h*t ]]
使用 (( )) 时,不需要空格分隔各值和运算符,使用 [[ ]] 时需要用空格分隔各值和运算符。

数字测试 -eq -ne -lt -le -gt -ge [[ ]]同 [ ]
文件测试 -r、-l、-w、-x、-f、-d、-s、-nt、-ot [[ ]]同 [ ]
字符串测试 = != -n -z [[ ]]同 [ ]
逻辑测试 []为 -a -o ! [[ ]] 为&& || !
数学运算 [] 不可以使用 [[ ]]可以使用+ - * / %
组合 均可用各自逻辑符号连接的数字(运算)测试、文件测试、字符测试

情况比较复杂的是字符的测试:字符测试
== 同= [ ]与[[ ]]同
<= >= 同=均不可以使用
< > 在 [] 内比较结果异常,如:$ [ 44 > 45 ] 与 $ [ 45 > 44 ]的返回值一样$ [ ccca > ccccb ]与$ [ ccccb > ccca ]的返回值一样
< >(首个单挑) 在[[]] 根据相应ASCII码比较(如果是多个字母或数字组合,则先比较首个,若相同则接着比较下一个)
> <(首个单挑) 在 [] 内根据相应ASCII码比较(如果是多个字母或数字组合,则先比较首个,若相同则接着比较下一个)
> < 在 [[]] 不可以使用

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2223569次
    • 积分:21586
    • 等级:
    • 排名:第352名
    • 原创:371篇
    • 转载:317篇
    • 译文:1篇
    • 评论:146条
    最新评论