一、条件测试
测试语句
在bash的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同的操作,
有时也会通过与if等条件语句相结合,让我们可以方便的完成判断。
格式1:test <测试表达式>
格式2:[<条件表达式>]
格式3:[[<条件表达式>]]
说明:
格式1和格式2是等价的。
格式3为扩展的test命令,有网友推荐用格式3。
提示1、测试文件是否存在
[root@node01 ~]# test -f file&& echo 1||echo 0
0
[root@node01 ~]# touch file
[root@node01 ~]# test -f file&& echo 1||echo 0
1
[root@node01 ~]# test ! -f file&& echo 1||echo 0 取反
0
2、中括号
[root@node01 ~]# [ -f file ]&& echo 1||echo 0
1
[root@node01 ~]# rm file
[root@node01 ~]# [ -f file ]&& echo 1||echo 0
0
[root@node01 ~]# [ ! -f file ]&& echo 1||echo 0
1
可以简写(不存在就不理他)
[root@node01 ~]# [ -f file ]||echo 0
[root@node01 ~]# [ -f file ]&& echo 1
1
双中括号
[root@node01 day6]# [[ -f file ]]&& echo 1||echo 0
0
[root@node01 day6]# [[ -f file ]]&& echo 1||echo 0
1
[root@node01 day6]# [[ -f file && -d dir ]]&& echo 1||echo 0
0
[root@node01 day6]# [[ -f file || -d dir ]]&& echo 1||echo 0
1
[root@node01 day6]# mkdir dir
[root@node01 day6]# [[ -f file || -d dir ]]&& echo 1||echo 0
1
二、总结
以上3种格式参数用法一样,只是语法会有区别,逻辑符等。
文件测试操作符
-e 该“文件”是否存在(常用)(exist)
-f 该“文件”是否为文件(file) (常用)
-s 文件的大小是否为0
-d 该“文件”是否为目录(directory)
-b 该“文件”是否为一个快设备(block)
-c 该“文件”是否为一个字符设备(char)
-S 该“文件”是否为一个套接字文件(socket)
-P 该“文件”是否为一个FIFO(管道)文件(pipe)
-L 该“文件”是否为一个连接文件。(link)
文件的“权限”检测,如 test -r filename
-r 检测该文件是否具有“可读”属性
-w 检测该文件是否具有“可写”属性
-x 检测该文件是否具有“可执行”属性
-u 检测该文件是否具有“SUID”属性
-g 检测该文件是否具有“SGID”属性
-k 检测该文件是否具有“Sticky bit”属性
-s 检测该文件是否为“非空白文件”
比较两个文件,如: test file1 -nt file2
-nt 判断file1是否比file2新(newer than)
-ot 判断file1是否比file2旧(older than)
-ef 判断file1与file2是否为同一个文件,可用于判断硬链接。主要判断两个文件是否均指向通过一个inode。(equal file)
更多用法请查看帮助(man test)
1、实例(针对于文件)
[root@node01 day6]# mkdir wolf
[root@node01 day6]# [ -f wolf ]&& echo 1||echo 0
1
[root@node01 day6]# mkdir wolf1
[root@node01 day6]# [ -f wolf1 ]&& echo 1||echo 0
0
[root@node01 day6]# [ -e wolf1 ]&& echo 1||echo 0
1
[root@node01 day6]# [ -d wolf1 ]&& echo 1||echo 0
1
[root@node01 day6]# [ -d wolf ]&& echo 1||echo 0
2、字符串测试
字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为0,字符串
是否为NULL(注:bash区分零长度字符串和空字符串)。
“=”比较两个字符串是否相同,与==等价,如if[ "$a" = "$b" ],其中$a这样的变量
最好用“”括起来,因为如果中间有空格,*等符号就可能出错,当然更好的方法就是
[ "${a}" = "${b}" ]。“!=” 比较两个字符串是否相同,不同则为“是”。
字符串比较符有如下4种(下面的字符串测试操作符号务必用""引起来):
= 测试两个字符串是否相等
!= 测试两个字符串是否不相等
-z 测试字符串是空字符串
-n 测试字符串是非空字符串
提示:
a、-n比较字符串长度是否不为0,如果不为0则为真,如[ -n "$wolf" ]
b、-z比较字符串长度是否等于0,如果等于0则为真,如[ -z "$wolf" ]
c、字符串比较符号两端最好有空格。多参考系统脚本。
d、字符串或者字符串变量比较都加双引号比较。
例子
[root@node01 day6]# [[ -n "abc" ]]&& echo 1||echo 0
1
[root@node01 day6]# [ -n "" ]&& echo 1||echo 0
0
[root@node01 day6]# laolang="wolf"
[root@node01 day6]# [ -n "$laolang" ]&& echo 1||echo 0
1
[root@node01 day6]# laolang=""
[root@node01 day6]# [ -n $laolang ]&& echo 1||echo 0 (这里不加双引号就有问题)
1
[root@node01 day6]# [ -n "$laolang" ]&& echo 1||echo 0
0
[root@node01 day6]# [ -z "$laolang" ]&& echo 1||echo 0
1
[root@node01 day6]# laolang="abc"
[root@node01 day6]# [ -z "$laolang" ]&& echo 1||echo 0
0
[root@node01 day6]# [ "abc" = "abd" ]&& echo 1||echo 0
0
[root@node01 day6]# [ "abc" = "abc" ]&& echo 1||echo 0
1
[root@node01 day6]# [ "abc" != "abc" ]&& echo 1||echo 0
0
[root@node01 day6]# [ "abc" != "abd" ]&& echo 1||echo 0
1
[root@node01 day6]# test=""
[root@node01 day6]# [ "$test" != "abd" ]&& echo 1||echo 0
1
[root@node01 day6]# test="abd"
[root@node01 day6]# [ "$test" != "abd" ]&& echo 1||echo 0
0
3、整数比较
在[]中使用的比较符,两个整数之间的判断,例如test n1 -eq n2
-eq 判断两数值相等(equal)
-ne 判断两数值不等(not equal)
-gt 判断n1大于n2(greater than)
-lt 判断n1小于n2(less than)
-ge 判断n1大于等于n2(greater than or equal)
-le 判断n1小于等于n2(less than or equal)
在(())和[[]]中使用的比较符
==或者= 判断两数值相等(equal)
!= 判断两数值不等(not equal)
> 判断n1大于n2(greater than)
>= 判断n1小于n2(less than)
< 判断n1大于等于n2(greater than or equal)
<= 判断n1小于等于n2(less than or equal)
注意:
a、=和!=在[]中使用不需要转义,包含“<”和“>”的符号在[]中使用需要转义,对于数字
不转义的结果未必会报错,但是结果可能会不对。
b、"<"符号的意思是小于,if[[ "$a" < "$b" ]],if[ "$a" < "$b" ].在[]中需要转义,
因为shell也用<和>重定向。
c、">"符号的意思是大于,if[[ "$a" > "$b" ]],if[ "$a" > "$b" ].在[]中需要转义,
因为shell也用<和>重定向。
d、比较最好用==
例子
[root@node01 day6]# [ 12 -eq 13 ]&&echo 1||echo 0
0
[root@node01 day6]# [ 12 -gt 13 ]&&echo 1||echo 0
0
[root@node01 day6]# [ 12 -lt 13 ]&&echo 1||echo 0
1
[root@node01 day6]# [ 12 < 13 ]&&echo 1||echo 0
-bash: 13: No such file or directory
0
[root@node01 day6]# [ 12 \< 13 ]&&echo 1||echo 0
1
[root@node01 day6]# [ 12 \> 13 ]&&echo 1||echo 0
0
[root@node01 day6]# [[ 12 > 13 ]]&&echo 1||echo 0
0
[root@node01 day6]# [[ 12 < 13 ]]&&echo 1||echo 0
1
[root@node01 day6]# [[ 12 = 13 ]]&&echo 1||echo 0
0
[root@node01 day6]# [[ 12 = 12 ]]&&echo 1||echo 0
1
[root@node01 day6]# (( 12 = 12 ))&&echo 1||echo 0 比较最好用==
-bash: ((: 12 = 12 : attempted assignment to non-variable (error token is "= 12 ")
0
You have new mail in /var/spool/mail/root
[root@node01 day6]# (( 12 == 12 ))&&echo 1||echo 0
1
4、逻辑操作符
多重条件判断
在[]中使用逻辑操作符
-a (and)两个条件同时成立。例如: test -r file -a -x file 若文件file具有可读和可执行权限,则为真。
-o (or)两个条件任何一个成立。例如: test -r file -o -x file 则file具有r或x权限时,就可以回传true
! 条件求反,如test ! -x file,当file 不具有x时,回传true
在[[]]中使用逻辑操作符
&& and与,两端都为真
|| or或,两端有一个为真
! not非,相反则为真
结论:-a&&的运算规则:只有两端都是1才是真;-o|| 两端都是0才为假,任何一端不为0都是真。
例子:
[root@node01 day6]# [ -f "$f1" -a -f "$f2" ]&& echo 1||echo 0
1
[root@node01 day6]# [[ -f "$f1" && -f "$f2" ]]&& echo 1||echo 0
1
[root@node01 day6]# [ -n "$f1" -a -z "$f2" ]&& echo 1||echo 0
0
[root@node01 day6]# [ -n "$f1" -o "$f2" ]&& echo 1||echo 0
1
[root@node01 day6]# [ -n "$f1" -o "$f2" = "$f1" ]&& echo 1||echo 0
1
[root@node01 day6]# n1=12;n2=13
[root@node01 day6]# [[ $n1 -eq $n2 && -z "$1" ]]&& echo 1||echo 0
0
[root@node01 day6]# [[ ! $n1 -eq $n2 && ! -z "$n1" ]]&& echo 1||echo 0
1