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