条件测试的语法:
在bash的各种流程控制结构中要进行各种测试,然后根据测试结果执行不同的操作,有时也会通过与if等条件语句相结合。
条件测试语法 | 说明 |
test < expression > | test命令进行条件测试表达式 |
[ expression ] | 单中括号进行条件测试表达式 |
[[ expression ]] | 双中括号进行条件测试表达式 |
(( expression )) | 双小括号进行条件测试表达式 |
说明:
1)test命令和[]是等价的。老师推荐使用单中括号。
2)[[]]为扩展的test命令,其中可以使用通配符等进行模式匹配。
3)&& || < > 等操作符可以应用于[[]]中,但是不能应用在[]中,在[]中一般使用-a -o -gt -lt 代替上面的操作。
4)整数的关系运算,也可以使用Shell的算术运算符(())。
5)我们可以通过man test能看到test的帮助文档信息。内容非常多。
6)test命令的测试功能很强大,但是和[] [[]]的功能有所重合。所以我们选择一种适合自己的语法就好了。
对文件存在不存在的一个测试:
[root@vm1 ~]# test -f file && echo true || echo false
false
[root@vm1 ~]# touch file
[root@vm1 ~]# test -f file && echo true || echo false
true
[root@vm1 ~]# test ! -f file && echo true || echo false
false
test -f /tmp/chang.txt && echo true
test -f /tmp/chang.txt || echo false
-z 选项是测试字符串是否为0,则表达式成立。
[root@vm1 ~]# char="chang"
[root@vm1 ~]# test -z "$char" && echo 1 || echo 0
0
[root@vm1 ~]# char=""
[root@vm1 ~]# test -z "$char" && echo 1 || echo 0
1
[]中括号条件测试语句:
中括号内部两端要有空格,[]和test是等价的,即test的所有判断选项都可以直接在[]里使用。
[root@vm1 ~]# [ -f file ] && echo 1 || echo 0
1
说明:
1)若中括号里面的命令执行成功(返回真)则执行&&后面的命令,否则执行||后面的命令。
2)另外,使用[]时的参数选项可以通过man test命令来获得帮助。
[[]]中括号的测试语句:
双中括号里面的两端也要有空格。
[root@vm1 ~]# [[ -f /tmp/chang.txt ]] && echo 1 || echo 0
0
[root@vm1 ~]# touch /tmp/chang.txt
[root@vm1 ~]#
[root@vm1 ~]# [[ -f /tmp/chang.txt ]] && echo 1 || echo 0
1
[root@vm1 ~]#
[root@vm1 ~]# [[ -f /tmp/chang.txt ]] && echo 1
1
[root@vm1 ~]# [[ -f /tmp/chang.txt ]] || echo 0
[root@vm1 ~]# rm -f /tmp/chang.txt
[root@vm1 ~]# [[ -f /tmp/chang.txt ]] && echo 1
[root@vm1 ~]# [[ -f /tmp/chang.txt ]] || echo 0
0
说明:[[]]操作符的用法,通过help test或man test查询即可得到帮助。
1)在[[]]中可以使用通配符等进行模式匹配;
2)&& || < > 等操作符可以应用于[[]]中,但是不能应用在[]中,在[]中一般使用-a -o -gt -lt 代替上面的操作。
3)不建议使用[[]]括号。
文件测试表达式:
在编程的时候需要处理一个对象,也应先对这个对象进行测试,只有确定它符合要求时才进行操作处理,这样做的好处就是避免程序出错及无谓的系统资源消耗,这个需要测试的对象可以是文件、字符串、数字等。
常用文件测试操作符 | 说明 |
-d |
文件存在且目录为真 |
-f | 文件存在且普通文件为真 |
-e | 文件存在则为真 |
-r | 文件存在且为可读则为真 |
-s | 文件存在且大小不为0则为真 |
-w | 文件存在且为可写则为真 |
-x | 文件存在且为可执行则为真 |
-L | 文件存在且为链接文件则为真 |
f1 -nt f2 | 文件1比文件2新,则为真 |
f1 -ot f2 | 文件1比文件2旧,则为真 |
更多用法请man test,或查看相关帮助。
测试文件的读、写、执行等属性,不光是根据文件属性rwx的标识来判断,还要看当前执行测试的用户是否真的可以按照对应的权限操作该文件。
一个特殊的例子:
[root@vm1 ~]# unset oldgirl
[root@vm1 ~]#
[root@vm1 ~]# echo $oldgirl
[root@vm1 ~]# [ -f $oldgirl ] && echo 1 || echo 0
1
[root@vm1 ~]# [ -f "$oldgirl" ] && echo 1 || echo 0
0
说明:
1)这是一个不存在的变量oldgirl。
2)不加引号测试变量,说明$oldgirl变量不存在内容还返回1,逻辑不对。加了引号进行测试,就返回为0,逻辑就是对的了。
[root@vm1 ~]# [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[root@vm1 ~]#
[root@vm1 ~]# [ -x /usr/sbin/$named ] || exit 5
说明:系统脚本是我们学习编程的第一标杆。
第二个命令更值得注意,只用了一部分判断,结果更加简洁。
特殊条件测试表达式:
[ 条件1 ] && {
命令1
命令2
命令3
}
[ 条件1 ] || {
命令1
命令2
命令3
}
说明:这是工作中比较常用替代if语句的方法。这种方式虽然比较简洁,但是不如if语句容易理解。
我们如果使用if语句,可以是这样的:
if [ 条件1 ] ; then
命令1
命令2
命令3
fi
字符串测试表达式:
常用字符串测试操作符 | 说明 |
-n " string" | 字符串长度不为0,则为真 |
-z "string" | 字符串长度为0,则为真 |
"string1" == "string2" | 字符串1等于字符串2 |
"string1 != "string2" | 字符串1不等于字符串2 |
说明:
1)对于字符串的测试,一定要将字符串加双引号之后再进行比较。
2)比较运算符==和!=两边必须要有空格。字符串比较的时候,若等号两端没有空格,则会导致判断出现逻辑错误,即使语法没有问题,但是结果依然不对。
我们对C语言比较了解,建议使用==,而不使用=,不等于使用!=,而不使用!==这个符号。符合我们自己的思路。
在写代码的时候,要多进行测试,跟踪。多练习,多思考。
整数二元比较操作符:
在[]即test中使用的比较运算符 | 在(()) [[]]中使用的比较运算符 | 说明 |
-eq | == 或 = | equal |
-ne | != | not equal |
-gt | > | greater than |
-ge | >= | greater equal |
-lt | < | less than |
-le | <= | less equal |
说明:
1)我们尽量是按照表格的方式来进行比较操作,以避免出现逻辑错误。
2)比较符号两端也要有空格。
逻辑操作符:
在[]即test中使用的逻辑运算符 | 在(()) [[]]中使用的逻辑运算符 | 说明 |
-a | && | and |
-o | || | or |
! | ! | not |
说明:
-a和-o逻辑操作符需要用在[]中。这个是比较常见的。
&&和||逻辑操作符可用于[[]]或(())中,也可以用在外部连接多个[]。
在[]和[[]]的两端及比较符号的两端,必须要有空格,但是对于(()),则不需要。
如果需要通配符,则使用[[]]双中括号。