shell脚本-条件测试命令


条件测试:判断某需求是否满足

条件测试命令

  • test EXPRESSION
  • [ EXPRESSION ]  #和test等价,建议使用[ ]
  • [[ EXPRESSION ]]       增强版的test,支持正色表达式和通配符

  注意:EXPRESSION前后必须有空白字符

 1、变量测试

#判断 NAME 变量是否定义
[ -v NAME ]
#判断 NAME 变量是否定义并且是名称引用
[ -R NAME ]

例:

[root@CentOS7 ~]# unset x
[root@CentOS7 ~]# test -v x
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# x=10
[root@CentOS7 ~]# test -v x
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# y=
[root@CentOS7 ~]# test -v y
[root@CentOS7 ~]# echo $?
0

#注意[ ]需要空格,否则会报命令错误
[root@CentOS7 ~]# [-v y]
-bash: [-v: command not found
[root@CentOS7 ~]# [ -v y ]
[root@CentOS7 ~]# echo $?
0

2、数值测试

-eq    是否等于
-ne    是否不等于
-gt    是否大于
-ge    是否大于等于
-lt    是否小于
-le    是否小于等于

例:

[root@CentOS7 ~]# i=10
[root@CentOS7 ~]# j=8
[root@CentOS7 ~]# [ $i -lt $j ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# [ $i -gt $j ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# [ i -gt j ]
-bash: [: i: integer expression expected

  算数表达式比较

<=
>=
<
>

例:

[root@CentOS7 ~]# x=10;y=20;(( x > y ));echo $?
1
[root@CentOS7 ~]# x=10;y=20;(( x < y ));echo $?
0

3、字符串测试

  test和[ ]用法

test和 [ ]用法
-z STRING    字符串是否为空,没定义或空为真,不空为假
-n STRING    字符串是否不空,不空为真,空为假
   STRING    同上

STRING1 = STRING2    是否等于," = "前后有空格
STRING1 != STRING2   是否不等于
>    ascii码是否大于ascii码
<    ascii码是否小于ascii码
EXPR1 -a EXPR2    测试条件EXPR1和EXPR2都为真则真,相当于“与”
EXPR1 -o EXPR2    测试条件EXPR1和EXPR2有一者满足就为真,相当于“或”

  [[ ]]用法

[[ expression ]] 用法
==    左侧字符串是否和右侧的PATTERN相同
      注意:此表达式用于[[  ]]中,PATTERN为通配符
=~    左侧字符串是否能够被右侧正则表达式的PATTREN匹配
      注意:此表达式用于[[  ]]中;扩展正则表达式

建议:当使用正则表达式或通配符使用[[  ]],其他清空一般使用[  ]

例1:使用[]

[root@CentOS7 ~]# unset str
[root@CentOS7 ~]# [ -z "$str" ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# str=""
[root@CentOS7 ~]# [ -z "$str" ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# str=" "
[root@CentOS7 ~]# [ -z "$str" ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# [ -n "$str" ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# !un
unset str
[root@CentOS7 ~]# [ -n "$str" ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# [ "$str" ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# str=magedu
[root@CentOS7 ~]# [ "$str" ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# str1=magedu
[root@CentOS7 ~]# str2=mage
[root@CentOS7 ~]# [ $str1 = $str2]
-bash: [: missing `]'
[root@CentOS7 ~]# [ $str1 = $str2 ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# [ $str1 != $str2 ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# [ `whoami` = "root" -a -e /data/a.txt ] && rm -f /data/a.txt;echo $?
0          #用户名为root并且/data/a.txt文件存在,则删除a.txt文件
[root@CentOS7 ~]# [ -e /data/a.txt -o -e /data/b.txt ];echo $?
0          #/data/a.txt或者/data/b.txt文件有一者存在,则为真
[root@CentOS7 ~]# ls /data/
a.txt

例2:在比较字符串时,建议变量放到" "中

[root@CentOS7 ~]# NAME="I love Linux"
[root@CentOS7 ~]# [ $NAME ]
-bash: [: love: binary operator expected
[root@CentOS7 ~]# [ "$NAME" ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# [ "I love Linux" ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# [ I love Linux ]
-bash: [: love: binary operator expected
[root@CentOS7 ~]#

例3:使用[[ ]]

#通配符
[root@CentOS7 ~]# FILE=test.log
[root@CentOS7 ~]# [[ "$FILE" == *.log ]]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# FILE=test.txt
[root@CentOS7 ~]# [[ "$FILE" == *.log ]]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# [[ "$FILE" != *.log ]]
[root@CentOS7 ~]# echo $?
0

#正则表达式
[root@CentOS7 ~]# [[ "$FILE" =~ \.log$ ]]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# FILE=test.log
[root@CentOS7 ~]# [[ "$FILE" =~ \.log$ ]]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# N=100
[root@CentOS7 ~]# [[ "$N" =~ ^[0-9]+$ ]]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# N=Magedu100
[root@CentOS7 ~]# [[ "$N" =~ ^[0-9]+$ ]]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# IP=1.2.3.4
[root@CentOS7 ~]# [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# IP=1.2.3.4567
[root@CentOS7 ~]# [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# [[ "$IP" =~ ^(([0-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@CentOS7 ~]# echo $?
1

#通配符
[root@CentOS7 ~]# NAME="linux1"
[root@CentOS7 ~]# [[ "$NAME" == linux* ]]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# [[ "$NAME" == "linux*" ]]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# NAME="linux*"
[root@CentOS7 ~]# [[ "$NAME" == "linux*" ]]
[root@CentOS7 ~]# echo $?
0
#结论:[[ == ]] ==右侧的*做为通配符,不要加"",只想做为*,需要加""或使用"\"转义

4、文件测试

存在性测试

-a FILE:          同-e
-e FILE:          文件存在为真,不存在为假
-b FILE:          是否存在且为块设备文件
-c FILE:          是否存在且为字符设备文件
-d FILE:          是否存在且为目录文件
-f FILE:          是否存在且为普通文件
-h FILE  或 -L FILE:   存在且为符号链接文件
-p FILE:          是否存在且为命名管道文件
-s FILE:          是否存在且为套接字文件

例:

[root@CentOS7 ~]# [ -a /etc/nologin ];echo $?
1
[root@CentOS7 ~]# ! [ -a /etc/nologin ];echo $?
0
[root@CentOS7 ~]# [ -d /etc ];echo $?
0
[root@CentOS7 ~]# [ -d /etc/issue ];echo $?
1
[root@CentOS7 ~]# [ -L /bin ];echo $?
0
[root@CentOS7 ~]# [ -L /bin/ ];echo $?
1

文件权限测试:

-r FILE:    是否存在且可读
-w FILE:    是否存在且可写
-x FILE:    是否存在且可执行
-u FILE:    是否存在且拥有suid权限
-g FILE:    是否存在且拥有sgid权限
-k FILE:    是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

例:

[root@CentOS7 ~]# [ -w /etc/shadow ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# [ -x /etc/shadow ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# touch test.txt
[root@CentOS7 ~]# [ -w test.txt ]
[root@CentOS7 ~]# echo $?
0
[root@CentOS7 ~]# chattr +i test.txt
[root@CentOS7 ~]# lsattr test.txt 
----i----------- test.txt
[root@CentOS7 ~]# [ -w test.txt ]
[root@CentOS7 ~]# echo $?
1
[root@CentOS7 ~]# chattr -i test.txt 
[root@CentOS7 ~]# [ -w test.txt ]
[root@CentOS7 ~]# echo $?
0

文件属性测试

-s FILE          是否存在且非空
-t fd            fd文件描述符是否在某终端已经打开
-N FILE          文件从上一次被读取之后是否被修改过
-O FILE          当前有效用户是否为文件属主
-G FILE          当前有效用户是否为文件数组
FILE1 -ef FILE2    FILE1是否是FILE2的硬链接
FILE1 -nt FILE2      FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2      FILE1是否旧于FILE2