替代test语句的[ ]和[[ ]]表达式有什么区别
时间:2005-03-25 来源:li2002
"[[",是关键字,许多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码比较(如果是多个字母或数字组合,则先比较首个,若相同则接着比较下一个)
> < 在 [[]] 不可以使用