shell脚本之测试命令(test、[])

话不多说,直接开车

在编写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   file1file2的新(修改日期)

file1 -ot file2   file1file2的旧(修改日期)

[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

(1)
MozartMozart
上一篇 2017-08-05 17:44
下一篇 2017-08-05 18:08

相关推荐

  • n28 第二周作业

    n28 第二周作业

    Linux干货 2017-12-09
  • linux iptables替代工具nftables

    1 使用 FirewallD 构建动态防火墙 1.1 “守护进程” 1.2 静态防火墙(system-config-firewall/lokkit) 1.3 使用 iptables 和 ip6tables 的静态防火墙规则 1.4 什么是区域? 1.4.1 预定义的服务 1.4.2 端口和…

    Linux干货 2015-03-11
  • 笔记整理:权限管理3-ACL

    ACL 访问控制列表,并不是所有的Linux文件系统,都支持ACL。FAT文件系统也不支持ACL   ACL文件系统中,不支持chmod等命令。同时不能更改文件权限。不存在文件权限。 问题提出 只让wang用户,对该文件不能够访问,同时不影响其他任何用户对该文件的操作。   ACL特点 针对单一用户或群组,单一文件或目录,进行rwx权限设…

    Linux干货 2016-08-05
  • 条件选择if语句

    单分支的if语句 if 判断条件; then 条件为真的分支代码 fi       单分支if结构的执行流程:首先判断条件测试操作的结果,如果返回值为0表示条件成立,则执行then后面的命令序列,一直到遇见fi为止表示结束,继续执行其他脚本代码;如果返回不为0,则忽略then后面的命令序列,直接跳至fi行以后执行其他脚…

    Linux干货 2016-08-16
  • N22-第三周作业

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 ~]# who | cut -d' ' -f1| uniq -u  执行前的情况:  执行后的情况:    &nbsp…

    Linux干货 2016-09-06
  • 啊 逗比呀!

    提示符,nano编辑,rz | sz命令,Sublime

    2017-11-19