Bash 包含强大的编程功能,其中包括丰富的可测试文件类型和属性的函数,以及在多数编程语言中可以使用的算术和字符串比较函数。理解不同的测试并认识到 shell 还能把一些操作符解释成 shell 元字符,是学好Bash编程的重要一环。
一、测试命令
Bash中一条命令退出状态码可作为测试条件,执行成功返回0,代表布尔类型true;反之执行失败返回1-255之间的错误代码,代表布尔类型false。
Bash的测试命令有:
-
test EXPRESSION
-
[ EXPRESSION ]
-
[[ EXPRESSION ]]
注意:2,3表达式EXPRESSION前后要有空白字符
其中1,2是等价的测试命令;3是2的复合命令形式,[ ]中表达式例如< > 等需要使用\转义表示,条件连接关系使用-a,-o。[[ ]]中表达式< >等符号不需要转义,条件连接关系使用&&,||。
二、&&和||
1.&&表示逻辑并关系
当多个条件使用&&连接,如果有一个条件为假,则返回假;全部为真,则返回真。
[cutemsyu@centos7 ~]$ true&&false&&true [cutemsyu@centos7 ~]$ echo $? 1 #条件有假,则返回假 [cutemsyu@centos7 ~]$ true&&true&&true [cutemsyu@centos7 ~]$ echo $? 0 #条件全为真,则返回真
2.||表示逻辑或关系
当多个条件使用||连接,如果有一个条件为真,则返回真;全部为假,则返回假。
[cutemsyu@centos7 ~]$ false||true||false [cutemsyu@centos7 ~]$ echo $? 0 [cutemsyu@centos7 ~]$ false||false||false [cutemsyu@centos7 ~]$ echo $? 1
3.and list,or list
&& 和||与命令结合构成链式命令结构,此结构提供一种有序执行命令的方法,有时可替代复杂的if/then语句。
(1)&& ——and list
command-1 && command-2 && …command-n
各个命令顺序执行,当某一命令返回值为假时,则链式命令中断执行。
[cutemsyu@centos7 ~]$ id root &>/dev/null && groups root &>/dev/null && echo "user:root and group:root both exist" user:root and group:root both exist [cutemsyu@centos7 ~]$ echo hello && echo world && false && ! hello world #最后的!没有打印出来
(2)|| ——or list
各个命令顺序执行,当某一命令返回值为真实,则链式命令中断执行
[cutemsyu@centos7 ~]$ false||false||echo hello ||echo world hello [cutemsyu@centos7 ~]$ false||true||echo hello ||echo world [cutemsyu@centos7 ~]$ #没有字符打印出来
(3)两者结合使用,完成if分支功能
[cutemsyu@centos7 ~]$ ping -W1 -c1 10.1.252.235 &>/dev/null && echo "ip is up" || echo "ip is down" ip is up [cutemsyu@centos7 ~]$ ping -W1 -c1 10.1.252.1 &>/dev/null && echo "ip is up" || echo "ip is down" ip is down
注意&&,|| 顺序
[cutemsyu@centos7 ~]$ ping -W1 -c1 10.1.252.1 &>/dev/null || echo "ip is down" && echo "ip is up" ip is down ip is up #这样写逻辑判断是错误的
三、数值测试
双目测试符
-eq | 是否等于 |
-ne | 是否不等于 |
-gt | 是否大于 |
-ge | 是否大于等于 |
-lt | 是否小于 |
-le | 是否小于等于 |
[cutemsyu@centos7 ~]$ test 1 -gt 2 && echo yes || echo no no [cutemsyu@centos7 ~]$ test 1 -gt 0 && echo yes || echo no yes
四、字符串测试
字符串比较时,都应该使用引号括起。避免字符串含有空白字符时发生报错!
单目测试符
-z "string" | 字符串长度是否为0 |
-n "string" | 字符串长度是否不为0 |
双目测试符
比较符号左右留空格
== | 是否相同 |
!= | 是否不相同 |
> | 是否大于,ASCII码比较 |
< | 是否小于,ASCII码比较 |
"string" =~ pattern |
字符串扩展正则匹配,也支持glob模式。 [[ ]]测试命令下使用;模式不能使用引号 |
[cutemsyu@centos7 ~]$ [[ "roots ssh" =~ r[a-z]{1}ts ]]&&echo yes ||echo no no [cutemsyu@centos7 ~]$ [[ "roots ssh" =~ r[a-z]{2}ts ]]&&echo yes ||echo no yes [cutemsyu@centos7 ~]$ [[ "roots ssh" =~ r??ts ]]&&echo yes ||echo no yes [cutemsyu@centos7 ~]$ [[ "roots ssh" =~ ^r.*sh$ ]]&&echo yes ||echo no yes [cutemsyu@centos7 ~]$ [[ "roots ssh" =~ "^r.*sh$" ]]&&echo yes ||echo no no #使用引号后,不能正确匹配
五、文件测试
单目测试符
(1)存在性及类型测试
-e | 文件是否存在 |
-f | 是否存在并且是普通文件 |
-d | 是否存在并且是目录文件 |
-h或-L | 是否存在并且是符号链接文件 |
-b | 是否存在并且是块设备文件 |
-c | 是否存在并且是字符设备文件 |
-p | 是否存在并且是管道文件 |
-S | 是否存在并且是套接字文件 |
(2)文件元数据测试
-s | 是否存在并且非空 |
-r | 是否存在且可读 |
-w | 是否存在且可写 |
-x | 是否存在且可执行 |
-u | 是否存在且有suid权限 |
-g | 是否存在且有sgid权限 |
-k | 是否存在且有sticky权限 |
-O | 当前有效用户是否为文件属主 |
-G | 当前有效用户是否为文件属组中成员 |
-t fd | fd(文件描述符)是否已在终端上打开 |
双目测试
file1 -ef file2 | 是否指向同一设备同一inode number |
file1 -ot file2 | file1 是否旧于 file2 |
file1 -nt file2 | file1 是否新于 file2 |
[cutemsyu@centos7 bin]$ ll /tmp/file1 ----------. 1 root root 0 Aug 10 16:37 /tmp/file1 [cutemsyu@centos7 bin]$ [ -r /tmp/file1 -o -w /tmp/file1 ]&&echo file is r or w ||echo file is no rw file is no rw #判断当前有效用户对/tmp/file1 是否不可读且不可写
原创文章,作者:cutemsyu,如若转载,请注明出处:http://www.178linux.com/35761