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

转载 2015年07月07日 10:08:09
首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。
"[[",是关键字,许多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码比较(如果是多个字母或数字组合,则先比较首个,若相同则接着比较下一个)
> < 在 [[]] 不可以使用

shell中if判断条件中使用[],[[]],(())还是test,let的比较

学习shell的时候总是被shell里的条件判断方式搞得头疼,经常不知道改 用[],[[]],(())还是test,let,而很少有书把它们的关系讲解的很清楚(应该是我悟性差或是看书太少),今天总结一...
  • nyist327
  • nyist327
  • 2015年04月01日 11:06
  • 1993

linux shell脚本中,关于test测试和if判断中常用的标志[-eq,gt..]

1. 关于某个文档的『文档类型』判断,如 test -e filename 表示存在否 -e 该『文档』是否存在(常用) -f 该『文档』是否存在且为档案(file)(常用) -d 该『文档』是...
  • u012906135
  • u012906135
  • 2016年07月15日 17:25
  • 2899

shell script学习(三)判断式的使用:test命令以及[ ]

shell script中的判断式,顾名思义就是判断一个式子是否满足一定的条件。在script中有如下几种实现方式: 1、使用test命令 先举个简单的例子,比如说判断在当前目录下判断一个文件scri...
  • u011321908
  • u011321908
  • 2014年01月21日 10:39
  • 4135

linux shell编程学习--test测试比较命令

本文介绍了linux shell自带test命令的各种用法。在linux shell编程过程中,如何使用test命令进行算术比较,文件属性,文件修改,字符串比较,以及逻辑表达式运算的操作。...
  • shuanghujushi
  • shuanghujushi
  • 2016年05月14日 12:57
  • 2527

汇编test和cmp区别

汇编test和cmp区别 看过破解教程,都知道test,cmp是比较关键,可是我一直不清楚它们究竟是怎么比较的,最后下决心找了很多资料,和大家一起把它们弄清楚. 首先看看:...
  • thanklife
  • thanklife
  • 2013年09月04日 15:57
  • 6561

TestNG入门——注解之@Test

TestNg提供的最基本的注解之一就是Test注解,作用在方法或者类上,此注解支持的属性有: 1、alwaysRun:提供一个false or true值,如果设置为true,则被标记的方法会永远被执...
  • haiweizhourong
  • haiweizhourong
  • 2017年02月08日 17:48
  • 682

玩转Bash脚本:test测试语句

之前写的这篇博文,最近发现讹误太多,又被多家网站(比如推酷,51CTO)转载过了。为避免误人子弟,贻害苍生。今特此更正:关于真值的讨论,尤其关于test测试字符串时的一些错误。还有莫名其妙的 -n 选...
  • guodongxiaren
  • guodongxiaren
  • 2014年08月05日 10:26
  • 3667

shell中if判断条件中使用[],[[]],(())还是test,let的比较

学习shell的时候总是被shell里的条件判断方式搞得头疼,经常不知道改 用[],[[]],(())还是test,let,而很少有书把它们的关系讲解的很清楚(应该是我悟性差或是看书太少),今天总结一...
  • nyist327
  • nyist327
  • 2015年04月01日 11:06
  • 1993

如何用maven运行特定的test case

最近碰到了一些特殊的问题,有些test case在IDE里面运行是可以pass的,但通过Maven运行就一定会出问题。这里不深入讨论,这类测试一般都是和entity manager有关的。今天记录一下...
  • u013613428
  • u013613428
  • 2016年06月07日 13:33
  • 6307

spring——依赖注入DI(spring-test方式)

spring——依赖注入DI(spring-test方式) 本文主要介绍如何实现spring 的依赖注入,并且浅显的讲述一下注入需要注意的事项。 1、创建一个maven项目 mvn archet...
  • wild46cat
  • wild46cat
  • 2017年05月01日 12:47
  • 515
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:替代test语句的[ ]和[[ ]]表达式有什么区别
举报原因:
原因补充:

(最多只允许输入30个字)