条件表达式


条件表达式的意义

条件表达式,我们非常的常用,可以说,任何编程语言,都离不开条件表达式,但是每种变成语言的写法都不太一样,在shell中,有一种独特的写法。

条件测试语句

条件测试语句,我们又叫做 test 语句。
格式 介绍
test 条件 常规判断命令
[[ 条件 ]] 支持运算符和正则的条件表达式
[ 条件 ] 常用条件表达式

文件表达式

表达式 含义 举例
-d 判断目录是否存在 test -d /etc
-f 判断文件是否存在 test -f /etc/passwd
-e 判断(文件目录)是否存在 tast -e /etc | test -e /etc/passwd
-r 判断文件是否有read权限 test -r /etc/hosts
-w 判断文件是否有write权限 test -w /etc
-x 判断文件是否有execute权限 test -x /bin/ls
-s 判断文件的大小是否大于0 test -s /etc/passwd
-L 判断文件是否为软连接文件 test -L /bin
file1 -nt file2 file1是否比file2更新,newer than test 1.txt -nt 2.txt
file1 -ot file2 file1是否比file2更旧,older than test 1.txt -ot 2.txt
#################### -d 判断目录是否存在 ##################
[root@m01 ~]# test -d /etc
[root@m01 ~]# echo $?
0
[root@m01 ~]# test -d /asdasda
[root@m01 ~]# echo $?
1
[root@m01 ~]# test -d /tmp && echo '目录存在' || echo '目录不存在'
目录存在
[root@m01 ~]# test -d /asdasdasd && echo '目录存在' || echo '目录不存在'
目录不存在
[root@m01 ~]# [ -d /tmp ] && echo '目录存在' || echo '目录不存在'
目录存在
[root@m01 ~]# [ -d /asda ] && echo '目录存在' || echo '目录不存在'
目录不存在
[root@m01 ~]# [[ -d /tmp ]] && echo '目录存在' || echo '目录不存在'
目录存在
[root@m01 ~]# [[ -d /asda ]] && echo '目录存在' || echo '目录不存在'
目录不存在


################### -f 判断文件是否存在 ####################
[root@m01 ~]# test -f /root/stu1.txt && echo '文件存在' || echo '文件不存在'
文件不存在
[root@m01 ~]# test -f /root/stu.txt && echo '文件存在' || echo '文件不存在'
文件存在

[[ -f /root/stu.txt ]] && echo '文件存在' || echo '文件不存在'
文件存在
[[ -f /root/stu1.txt ]] && echo '文件存在' || echo '文件不存在'
文件不存在

[ -f /root/stu.txt ] && echo '文件存在' || echo '文件不存在'
文件存在
[ -f /root/stu1.txt ] && echo '文件存在' || echo '文件不存在'
文件不存在


################ -e 判断文件目录是否存在 ################
[root@m01 ~]# test -e /etc/
[root@m01 ~]# echo $?
0
[root@m01 ~]# test -e /root/500.txt
[root@m01 ~]# echo $?
1
[root@m01 ~]# test -e /root/stu1.txt && echo '存在' || echo '不存在'
不存在
[root@m01 ~]# test -e /root/stu.txt && echo '存在' || echo '不存在'
存在
# [[]]
[[ -e /root/stu.txt ]] && echo '存在' || echo '不存在'
存在
[[ -e /root/stu1.txt ]] && echo '存在' || echo '不存在'
不存在
# []
[ -e /root/stu.txt ] && echo '存在' || echo '不存在'
存在
[ -e /root/stu1.txt ] && echo '存在' || echo '不存在'
不存在


################ -r -w -x 判断文件是否有。读取-写入-执行。权限 #################
[xxx@m01 ~]$ test -r 2.txt
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ test -r 3.txt
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ test -r 2.txt && echo 'can read' || echo 'cant read'
cant read
[xxx@m01 ~]$ test -r 1.txt && echo 'can read' || echo 'cant read'
can read
[xxx@m01 ~]$ [ -w 2.txt ] && echo 'can write' || echo 'cant write'
can write
[xxx@m01 ~]$ [ -w 1.txt ] && echo 'can write' || echo 'cant write'
cant write
[xxx@m01 ~]$ [[ -w 2.txt ]] && echo 'can write' || echo 'cant write'
can write
[xxx@m01 ~]$ [[ -w 1.txt ]] && echo 'can write' || echo 'cant write'
cant write


################### -s 判断文件大小是否为0 (空文件) ############
文件如果是空的 返回值是非0
文件如果是非空 返回值是0
[xxx@m01 ~]$ test -s 2.txt && echo 'not null' || echo 'null'
not null
[xxx@m01 ~]$ test -s 1.txt && echo 'not null' || echo 'null'
null
[ -s 2.txt ] && echo 'not null' || echo 'null'
[[ -s 2.txt ]] && echo 'not null' || echo 'null'


################## -L 判断文件是否为软连接 ###################
如果是软连接 返回值是0
如果不是软连接 返回值是非0
[xxx@m01 ~]$ test -L 2.txt
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ test -L test/niubi.txt
[xxx@m01 ~]$ echo $?
0
[[ -L test/niubi.txt ]] && echo '是软连接' || echo '不是软连接'
[ -L test/niubi.txt ] && echo '是软连接' || echo '不是软连接'


################## -nt -ot 判断那个文件更新时间更新 ############
-nt newer than
前者旧 返回值非0 根据文件的时间戳去比较
前者新 返回值是0
[xxx@m01 ~]$ test 1.txt -nt 2.txt
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ test 2.txt -nt 1.txt
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ [ 2.txt -nt 1.txt ] && echo '前者新' || echo '后者新'
前者新
[xxx@m01 ~]$ [ 1.txt -nt 2.txt ] && echo '前者新' || echo '后者新'
后者新
[xxx@m01 ~]$ [[ 2.txt -nt 1.txt ]] && echo '前者新' || echo '后者新'
前者新
[xxx@m01 ~]$ [[ 1.txt -nt 2.txt ]] && echo '前者新' || echo '后者新'
后者新

-ot older than
前者旧 返回值是0 根据文件的时间戳去比较
后者旧 返回值是非0
[xxx@m01 ~]$ test 1.txt -ot 2.txt
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ test 2.txt -ot 1.txt
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ [ 1.txt -ot 2.txt ] && echo '前者旧' || echo '后者旧'
前者旧
[xxx@m01 ~]$ [ 2.txt -ot 1.txt ] && echo '前者旧' || echo '后者旧'
后者旧
[xxx@m01 ~]$ [[ 1.txt -ot 2.txt ]] && echo '前者旧' || echo '后者旧'
前者旧
[xxx@m01 ~]$ [[ 2.txt -ot 1.txt ]] && echo '前者旧' || echo '后者旧'
后者旧

字符串表达式

字符串表达式介绍
注意:大写的注意,在shell脚本中所有变量的调用,请一定加上双引号,尤其是和字符串相关的,千言
万语汇成一句话"加双引号"如果让我看见你不加,那么你帽子颜色和加双引号一个颜色。
表达式 含义 举例
-n not null 非空及成立 test -n 'kjt'
-z null 空则成立 test -z 'kjt'
"str1" = "str2" 等号左边字符串与右边字符串相等则成立 test 'zls' = 'cls'
"str1" != "str2" 等号左边字符串与右边字符串不等则成立 test 'zls' != 'cls'
###############-z null 空则成立 ###########################
#字符串没有被赋值/赋值为空
#返回值是0
[xxx@m01 ~]$ test -z "$name"
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ name=xxx
[xxx@m01 ~]$ test -z "$name"
[xxx@m01 ~]$ echo $?
1

#################### -n not null 非空则成立 #################
#字符串被赋值过
#返回值是0
[xxx@m01 ~]$ echo $name
xxx
[xxx@m01 ~]$ test -n "$name"
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ test -n "$name"
[xxx@m01 ~]$ echo $?
1

################### "str1" = "str2" ##########################
[xxx@m01 ~]$ test 'abc' = 'abc'
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ test 'abc' = 'abc1'
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ [ 'abc' = 'abc' ] && echo '左右一致' || echo '左右不一致'
左右一致
[xxx@m01 ~]$ [ 'abc1' = 'abc' ] && echo '左右一致' || echo '左右不一致'
左右不一致

##################### "str1" != "str2" #######################
[xxx@m01 ~]$ test 'abc' != 'abc'
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ test 'abc' != 'abc1'
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ [ 'abc' != 'abc' ] && echo '左右不相同' || echo '左右相同'
左右相同
[xxx@m01 ~]$ [ 'abc1' != 'abc' ] && echo '左右不相同' || echo '左右相同'
左右不相同

整数表达式

表达式 含义 test举例 [[ ]]举例
-eq equal 等于 test 2 -eq 2 [[ 2 -eq 2 ]]
-ne not equal 不等于 test 2 -ne 2 [[ 2 != 2 ]]
-gt great than 大于 test 2 -gt 2 [[ 2 > 2 ]]
-ge great equal 大于等于 test 2 -ge 2 [[ 2 >= 2 ]]
-lt less than 小于 test 2 -lt 2 [[ 2 < 2 ]]
-le less equal 小于等于 test 2 -le 2 [[ 2 <= 2 ]]
######################### 注意事项 #########################
test 1 -eq 2
[ 1 -eq 1 ]
[[ 1 -eq 1 ]]

# 单括号使用> 会识别为重定向
[xxx@m01 ~]$ [ $age > 20 ] && echo 'success' || echo 'fail'
success
[xxx@m01 ~]$ ll
total 4
-rw-rw-r-- 1 xxx xxx 0 Jul 5 11:32 20

# 小问题
[xxx@m01 ~]$ echo $age
20
[xxx@m01 ~]$ [ $age \> 3 ] && echo 'success' || echo 'fail'
fail
[xxx@m01 ~]$ [ $age \> 10 ] && echo 'success' || echo 'fail'
success
[xxx@m01 ~]$ [ $age \> 4 ] && echo 'success' || echo 'fail'
fail

# 原因 因为排序问题 20要小于3
[xxx@m01 ~]$ seq 20 | sort
1
10
18
19
2
20
3

# 所以 能用-gt 就 不要用 >
[xxx@m01 ~]$ [ $age -gt 4 ] && echo 'success' || echo 'fail'
success
[xxx@m01 ~]$ [ $age -gt 3 ] && echo 'success' || echo 'fail'
success
[xxx@m01 ~]$ [ $age -gt 10 ] && echo 'success' || echo 'fail'
success
[xxx@m01 ~]$ [ $age -gt 10 ] && echo 'success' || echo 'fail'

逻辑运算表达式

表达式 含义 符号
非,取反
&& 与,和,同时成功 -a
|| 或者,一个成功即可 -o
# && = and
[ $num1 -eq 0 -a $num2 -eq 3 ]
# || = or
[ $num1 -eq 0 -o $num2 -eq 3 ]
# !
[ $num1 -ne 0 -a $num2 -ne 3 ]
# and | &&
a和b 都得满足
# or | ||
a和b 满足一个

image-20240705151725019

[[ ]]的成员运算---包含判断 =~

##################  =~ 成员运算 ############################
# 前面的值包不包含你的输入
[xxx@m01 ~]$ [[ $name =~ 'k' ]]
[xxx@m01 ~]$ echo $?
0
[xxx@m01 ~]$ [[ $name =~ 'j' ]]
[xxx@m01 ~]$ echo $?
1
[xxx@m01 ~]$ [[ $name =~ 'j' ]] && echo 'baohan' || echo 'bubaohan'
bubaohan
[xxx@m01 ~]$ [[ $name =~ 'a' ]] && echo 'baohan' || echo 'bubaohan'
baohan

# 关于数字的坑
# 3.判断变量是否只有数字
## 方法一: expr
## 方法二:
[root@zabbix01 script]# name=6
[root@zabbix01 script]# [[ $name =~ ^[0-9]$ ]] && echo '只有数字' || echo '木有数
字'
只有数字

## 但是如果这样,只能匹配一个数字
[root@zabbix01 script]# name=66
[root@zabbix01 script]# [[ $name =~ ^[0-9]$ ]] && echo '只有数字' || echo '木有数字'
木有数字

## 那么我们就得再加一个
[root@zabbix01 script]# [[ $name =~ ^[0-9][0-9]$ ]] && echo '只有数字' || echo '木有数字'
只有数字

if ----判断

分支

#################### 单分支 ###################
# 方法1
if [ 条件1 ];then
	动作1
	动作2
fi
# 方法2
if [ 条件1 ]
then
	动作1
	动作2
fi

###################### 多分支 ###################
# 方法1
if [ 条件1 ];then
	动作1
	动作2
else
	动作1
	动作2
fi
# 方法2
if [ 条件1 ]
then
	动作1
	动作2
else
	动作1
	动作2
fi


################# 多分支 ######################
if [ 条件1 ]
then # 满足条件1 执行三个动作
	动作1
	动作2
elif [ 条件2 ]
then # 不满足条件1 满足条件2 执行三个动作
	动作1
	动作2
elif [ 条件3 ]
then # 不满足条件1 也不满足条件2 满足条件3的执行三个动作
	动作1
	动作2
else # 不满足条件1 也不满足条件2 & 条件3 执行三个动作
	动作1
fi

# 方法1
if [ 条件1 ];then # 满足条件1 执行三个动作
	动作1
	动作2
elif [ 条件2 ];then # 不满足条件1 满足条件2 执行三个动作
	动作1
	动作2
elif [ 条件3 ];then # 不满足条件1 也不满足条件2 满足条件3的执行三个动作
	动作1
	动作2
else # 不满足条件1 也不满足条件2 & 条件3 执行三个动作
	动作1
	动作2
fi