玩转Bash脚本:test测试语句

总第1篇
test就是测试的意思,常用在流程控制语句中作为条件。下面做一下介绍。

关于真值

与其他语言不同,Bash(包括其他Shell)中,是用0表示真,非0表示假的。
之所以用0表示成功,而不是1来表示。我认为也是有一定道理的,因为成功的情况只有一种,而出错的可能却有许多,所以用正数来表示错误。不同的正数代表着不同的错误,所以一般情况下可以通过正数的值来判断是出了什么错误。

如果你有过POSIX编程经验(比如Linux下C编程),你会知道一个errno的东西。你也会知道大量的if语句用来测试一个函数的调用结果,每个函数基本上都是返回0时表示操作成功,而如果返回非0则出错,此时你也要exit(0)。

下面言归正传

测试整数

基本规则

整数的test就是大小关系的比较,与其他语言不同,Bash中没有使用<,>来做大于等于号,而是使用了减号开头的选项来比较。

假如有两个整数变量a和b。那么比较a是否大于b,就写作test $a -gt $b,符合条件返回真值0。
实际在终端里测试的时候可以这样写来看test语句的执行结果:

test $a -gt $b && echo Yes

如果条件成立打印 Yes,不成立不打印。

全部选项

选项 描述 英文全称
eq 等于 equal
gt 大于 greater than
lt 小于 less than
ne 不等于 not equal
ge 大于等于 greater or equal
le 小于等于 less or equal

注意:

每个选项前需要有一个短横线-
还要注意的是使用以上操作符,那么操作符两边一定要是整数。
在Bash中,即使给整数加了引号,比如"123",也视作整数。但如果某一位含有整数[0-9]以外的字符比如,12a,"12a",则不行。

Bash脚本,或者说Shell终端中的各种命令都有很丰富的选项,所以我建议在记忆的时候要去记忆它的英文全称,理解了它的含义,这样反而会降低记忆的难度。

测试字符串

字符串的测试无非就是包括,判断两个字符串是否相等,判断一个字符串是否为空。
假设str1和str2是持有两个字符串的变量(直接测试两个字符串,而非字符串变量时,则不加$,这很好理解)。具体用法为:

用法 描述
test $str1 = $str2 测试是否相等,相等返回0
test $str1 != $str2 测试是否不等,不等返回0
test $str1 \< $str2 如果str1的字典序在str2之后,则返回0
test $str1 \> $str2 如果str1的字典序在str2之前,则返回0
test $str1 总是返回0
test -n $str1 如果不为空返回0
test -z $str1 如果是空串,返回0

关于字典序的那两个比较,其实就是大于号>和小于号<。因为bash中这两个符号有重定向的意思,所以这里要使用反斜杠\ 转义。

#在bash中一个好的习惯就是在引用变量的时候加上双引号。

比如下面:

特别注意
选项-n是 nonzero 的缩写,理解为长度不为0但需要特别指出的是:-n选项测试时请将引用变量外加上双引号。
Bash中的引用变量的方法有很多种,我认为此处应该是加不加双引号无所谓的。囧。。
经测试,如果我有当前未定义变量var(或者定义为var=""),那么理论上讲,var就是空串。
test -n $var应该是返回1(假)的,因为他的长度是0。但其实此时无论var是否为空串都会返回真值0。
但是加上双引号(注意不能是单引号),也就是test -n "$var",效果就能如期,即只有在var为空的时候返回真值0。
而选项-z(是 zero 的缩写,理解为长度为0)引用变量的时候加不加双引号无所谓。

测试文件

测试文件需要用到大量的选项,这里我只写一个常用的,其他的大家自行man test

针对单个文件

选项 描述
d 是否为目录
f 是否为普通文件
x 是否有执行权限
r 是否有读权限
w 是否写读权限
e 是否存在
s 文件大小是否大于0
c 是否为字符设备文件
b 是否为块设备文件

以上条件在成立的时候返回真值0。具体用法比如:

test -f hello.c
test -d /home

针对两个文件

用法 描述
test file1 -nt file2 测试file1的修改时间是不是比file2 new(新)
test file1 -ot file2 测试file1的修改时间是不是比file2 old(旧)
test file1 -ef file2 测试两者是相同的设备和具有相同的结点(inode)数

同样的,若是条件成立则返回真值0,否则返回假值1。注意这里的file1,file2就是文件名的字符串了。

#可以直接test a.c -nt b.c
#或者是
a=a.c
b=b.c
test $a -nt $b

不再细表。

逻辑运算

逻辑运算就是与或非。Bash中同样有&&,||但是并非是在test内部,而是用来组合多条shell语句,前面我们应该看到过了,只有当&&前面的语句执行成功时,才执行后面的语句。而在test内部:

运算符 描述
-a 逻辑与
-o 逻辑或
! 逻辑非

用法如:

test $a -lt $b -a $a -gt $c
test $a -lt $b -o $a -gt $c
test ! -d sleep.sh && echo Yes #如果sleep.sh不是目录,就打印Yes

其实完整版是这样:

test $a -lt $b -a test $a -gt $c
test $a -lt $b -o test $a -gt $c 

简化版test

在读完这一部分后,你可能会惊呼,怎么不早点告诉我。哈哈。

其实以上所有的test命令都可以用方括号替换。比如

test -f hello.c

可以换成

[ -f hello.c ]

怎么样,很方便吧。注意的是,方括号和表达式前后各有一个空格间隔哦。不要丢掉。实际也就是 [空格-f hello.c空格]

其他注意的地方是方括号的逻辑表达式,比如

test $a -lt $b -a $a -gt $c

可以转化为

[ $a -lt $b -a $a -lt $c ]

或者分开作为两条语句

[ $a -lt $b -a ]&&[ $a -lt $c ]

这个&&并无什么特别之处,并非方括号运算所独有。此处就是当前面语句为真(即返回0)时,接着执行后面的语句。所有的Bash语句都可以用&&或||连接。

test是Shell的外部命令,而[ ]是Shell内置的操作符。


posted on 2014-08-05 10:26  果冻虾仁  阅读(182)  评论(0编辑  收藏  举报

导航