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
下一篇 2017-08-05

相关推荐

  • linux用户和权限管理

    0.用户 1、建用户:adduser nuoline //新建nuoline用户passwd nuoline //给nuoline用户设置密码 2、建工作组groupadd test //新建test工作组 3、新建用户同时增加工作组useradd -g test nuoline //新建phpq用户并增加到test工作组 注:…

    Linux干货 2016-08-05
  • 用户管理、组管理、权限管理、文本处理工具应用示例

    用户管理、组管理、权限管理、文本处理工具应用示例 1.复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其他用户均没有任何访问权限 [root@localhost ~]# cp -a /etc/skel/ /home/tuser1/ [root@localhost ~]# chmod -R go= /hom…

    Linux干货 2017-07-23
  • 条件判断if、case与文件查找locate、find及相关练习

    一、条件选择 1、if:按条件执行脚本中的内容,可以使用嵌套结构,有单分支、双分支和多分支结构,每个条件中可以有不止一条语句,如果有多条语句,可以用and(-a)或or(-o)连接在一起,但不能使用&&或||: if COMMANDS; then     COMMANDS;   &n…

    Linux干货 2016-08-18
  • N26-第七周

    1、创建一个10G分区,并格式为ext4文件系统;   (1) 要求其block大小为2048, 预留空间百分比为2, 卷标为MYDATA, 默认挂载属性包含acl;    (2) 挂载至/data/mydata目录,要求挂载时禁止程序自动运行,且不更新文件的访问时间戳; [root@localhost ~]# fdi…

    Linux干货 2017-03-05
  • Shell 编 程 之 until循 环 语 句-20160817

    Shell 编 程 之 until循 环 语 句 §·练习题: 1 每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并提示该用户退出系统? 解:解题思路:按照题意该脚本一直无限循环,一直探测用户h…

    Linux干货 2016-08-22
  • gzip压缩算法

    gzip,zlib,以及图形格式png,使用的是同一个压缩算法deflate。我们通过对gzip源码的分析来对deflate压缩算法做一个详细的说明: 第一,gzip压缩算法基本原理的说明。 第二,gzip压缩算法实现方法的说明。 第三,gzip实现源码级的说明。 1. Gzip压缩算法的原理      &n…

    Linux干货 2015-07-30