话不多说,直接开车
在编写shell脚本中,我们经常需要判断命令执行的正确与否,从而进行不同的操作。首先我们来介绍下条件性的执行操作符:根据退出状态而定,命令可以有条件地运行。其中,利用echo的话方便我们对测试结果的查看。
(1)&& 代表条件性的AND THEN
可以理解为短路与:当&&前面命令为真时,执行&&符号后的内容。当前面命令为假,不执行&&后面的内容。
[root@localhost ~]#cd /etc/ && echo true true [root@localhost etc]#cd /etc123/ && echo true -bash: cd: /etc123/: No such file or directory
[root@localhost etc]#cd /etc123/ 2> /dev/null && echo true #将错误输出定向到黑洞(/dev/null)里面 [root@localhost etc]#
(2)|| 代表条件性的OR ELSE
可以理解为短路或:当||前面命令为真时,不执行||符号后的内容。当前面命令为假,执行||后面的内容。
[root@localhost etc]#cd /etc/ || echo false [root@localhost etc]# [root@localhost etc]#cd /etc123/ 2> /dev/null || echo false false
两者可以结合判断显示,更加直观:
[root@localhost etc]#cd /etc/ && echo ture || echo false ture #cd /etc/ 命令为真,执行&&后面的内容,不再去管||符号 [root@localhost etc]#cd /etc123/ 2> /dev/null && echo ture || echo false false #cd /etc/ 命令为假,不执行&&后面的内容,跳到执行||后面内容。
虽然对于命令可以直接判断执行正确或错误,但许多情况下无法直接用命令解决,于是,铛铛铛铛铛,出现了测试命令,Linux的Shell中存在一组测试命令,该组命令用于测试某种条件或某几种条件是否真实存在。测试命令是判断语句和循环语句中条件测试工具,对于编写Shell非常重要。
测试命令用于测试表达式的条件的真假。如果测试的条件为真,则返回一个0值;如果测试条件为假,将返回一个非0整数值。
测试命令有两种结构,一种是用test命令进行测试,结构如下:
test expression
其中,条件expression是一个表达式,该表达式可为数字、字符串、文本和文件属性的比较,同时可同时加入各种算术、字符串、文本等运算符。
为了提高命令的可读性,经常使用第二种格式:
[ expression ]
其中“[”是启动测试命令,但要求在expression后要有一个“]”与其配对。使用该命令要特别注意“[”后和“]”前的空格必不可少。第二种格式常用。
两类测试命令
Test :如:
[root@localhost ~]#A=123 #定义变量 [root@localhost ~]#B=0123 #定义变量 [root@localhost ~]#test "$A" == "$B" && echo true || echo false false [root@localhost ~]#test "$A" -eq "$B" && echo true || echo false true
[ :如
[root@localhost ~]#[ "$A" == "$B" ] && echo true || echo false false [root@localhost ~]#[ "$A" -eq "$B" ] && echo true || echo false true #注意“[”后和“]”前的空格必不可少,这种格式比较常用
常用表达式:
-v VAR
变量VAR是否设置,设置为真
[root@localhost ~]#A=123 [root@localhost ~]#[ -v A ] && echo true || echo false true [root@localhost ~]#[ -v a ] && echo true || echo false false
#字符串比较
== :字符串是否相等
> :前者ASCII码是否大于后者ASSCII码
< :前者ASCII码是否小于后者ASSCII码
!= :字符串是否不相等
=~ :左侧字符串是否能够被右侧的PATTERN所匹配
注意:此表达式一般用于[[]]中;扩展的正则表达式的PATTERN(模式)
[root@localhost ~]#[[ "123456" =~ [0-9]{6} ]] && echo ture || echo false ture [root@localhost ~]#[[ "123456" =~ [0-9]{7} ]] && echo ture || echo false false #注意:扩展正则表达式不需要加双引号
-n :string检查字符串长度不为0(等价test string)
-z :string检查字符串长度为0
[root@localhost ~]#[ -n "abc" ] && echo ture || echo false ture [root@localhost ~]#test "abc" && echo ture || echo false ture [root@localhost ~]#test "" && echo ture || echo false false [root@localhost ~]#[ -n "" ] && echo ture || echo false false [root@localhost ~]#[ -n " " ] && echo ture || echo false ture
[root@localhost ~]#A= #定义A变量,不输入任何字符,直接回车 [root@localhost ~]#[ -n "$A" ] && echo ture || echo false false
注意:用于字符串或者引用变量比较时的用到的操作数都应该使用双引号
#数字比较
int1 -eq int2 int1等于int2
int1 -ne int2 int1不等于int2
int1 -ge int2 int1大于等于int2
int1 -gt int2 int1大于int2
int1 -le int2 int1小于等于int2
int1 -lt int2 int1小于int2
[root@localhost ~]#A=0123 [root@localhost ~]#B=123 [root@localhost ~]#[ "$A" -eq "$B" ] && echo true || echo false true [root@localhost ~]#[ "$A" -ge "$B" ] && echo true || echo false true [root@localhost ~]#[ "$A" -ne "$B" ] && echo true || echo false false
#文件比较
file1 -ef file2 文件的设备和节点号相同
file1 -nt file2 file1比file2的新(修改日期)
file1 -ot file2 file1比file2的旧(修改日期)
[root@localhost mnt]#cp /etc/passwd . #拷贝文件放到当前目录 [root@localhost mnt]#ln passwd mima #设置硬链接,硬链接本质就像一个文件多个文件名,文件的本质(节点号)一样,只是文件名不同而已。 [root@localhost mnt]#ls mima passwd [root@localhost mnt]#[ passwd -ef mima ] && echo true || echo false true [root@localhost mnt]#touch file1 file2 #同时创建文件 [root@localhost mnt]#stat file1 file2 #查看文件时间戳,包括修改时间Modify ................ [root@localhost mnt]#touch -m file2 #touch -m 仅仅更新文件的修改时间 [root@localhost mnt]#stat file1 file2 ................ [root@localhost mnt]#[ file1 -nt file2 ] && echo true || echo false false [root@localhost mnt]#[ file1 -ot file2 ] && echo true || echo false true
#文件判断
-b filename | 当filename 存在并且是块文件时返回真(返回0) |
-c filename | 当filename 存在并且是字符文件时返回真 |
-d pathname | 当pathname 存在并且是一个目录时返回真 |
-e pathname | 当由pathname 指定的文件或目录存在时返回真 |
-f filename | 当filename 存在并且是正规文件时返回真 |
-g pathname | 当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真 |
-h filename | 当filename 存在并且是符号链接文件时返回真 (或 -L filename) |
-k pathname | 当由pathname 指定的文件或目录存在并且设置了”粘滞”位时返回真 |
-p filename | 当filename 存在并且是命名管道时返回真 |
-r pathname | 当由pathname 指定的文件或目录存在并且可读时返回真 |
-s filename | 当filename 存在并且文件大小大于0 时返回真 |
-S filename | 当filename 存在并且是socket 时返回真 |
-t fd | 当fd 是与终端设备相关联的文件描述符时返回真 |
-u pathname | 当由pathname 指定的文件或目录存在并且设置了SUID 位时返回真 |
-w pathname | 当由pathname 指定的文件或目录存在并且可写时返回真 |
-x pathname | 当由pathname 指定的文件或目录存在并且可执行时返回真 |
-O pathname | 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写) |
-G pathname | 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真 |
最后说一下组合测试:
第一种方式:
COMMAND1 && COMMAND2 逻辑关系:并且
COMMAND1 || COMMAND2 逻辑关系:或者
! COMMAND 逻辑关系:非
EXPRESSION1 && EXPRESSION2 逻辑关系:并且
EXPRESSION1 || EXPRESSION2 逻辑关系:或者
! EXPRESSION 逻辑关系:非
如:
[root@localhost app]#( cd /etc/ && cd /app/ 2> /dev/null ) && echo true || echo false true [root@localhost app]#( cd /etc/ && cd /app123/ 2> /dev/null ) && echo true || echo false false [root@localhost app]#([[ -n "123" ]] && [[ -n "" ]]) && echo true || echo false false [root@localhost app]#([[ -n "123" ]] && [[ -n "123" ]]) && echo true || echo false true
第二种方式:必须使用测试命令进行
EXPRESSION1 -a EXPRESSION2 逻辑关系:并且
EXPRESSION1 -o EXPRESSION2 逻辑关系:或者
! EXPRESSION 逻辑关系:非
如:
[root@localhost app]#[ -n "123" -a -n "12" ] && echo ture || echo false ture [root@localhost app]#[ -n "123" -a -n "" ] && echo ture || echo false false [root@localhost app]#[ -n "123" -o -n "" ] && echo ture || echo false ture
原创文章,作者:Mozart,如若转载,请注明出处:http://www.178linux.com/83716