一、条件测试操作
Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0(真true)时表示成功,返回值为非0值(假false)时表示失败或异常
-
test命令
测试表达式是否成立,若成立返回为0,否则返回其他数值($?返回值为 0 表示条件成立)
test 条件表达式
[ 条件表达式 ] #方括号“[”或“]”与条件表达式之间需要至少一个空格进行分隔
-
文件测试
[ 操作符 文件或目录 ]
- 常用的测试操作符
-e | 测试目录或文件是否存在(Exist) |
-d | 测试是否为目录(Directory) |
-f | 测试是否为文件(File) |
-r | 测试当前用户是否有权限读取(Read) |
-w | 测试当前用户是否有权限写入(Write) |
-x | 测试是否设置有可执行(Excute)权限 |
-L | 测试是否为符号链接 |
-
整数值比较
[ 整数1 操作符 整数2 ]
- 常用的测试操作符
-eq | 等于 |
-ne | 不等于 |
-gt | 大于 |
-lt | 小于 |
-le | 小于等于 |
-ge | 大于等于 |
[[ 运算表达式 选项 整数 ]] #若进行数学运算则需多加[]
-
字符串比较
[ 字符串1 = 字符串2 ] 或 [[ 字符串1 == 字符串2 ]] #相同
[ 字符串1 != 字符串2 ] 或 [[ 字符串1 != 字符串2 ]] #不相同[ -z 字符串 ]
[[ 字符串1 =~ 字符串2 ]] #包含
[ -z "字符串" ] #检查字符串是否为空(Zero),对于未定义或赋予空值的变量将视为空串
[ -n "字符串" ] #检查是否有字符串存在
-
逻辑测试
[ 表达式1 ] 操作符 [ 表达式2 ]
命令1 操作符 命令2
[[ 表达式1 操作符 表达式2 ]] #&&、||操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错
- 常用的测试操作符
-a或&& | 逻辑与,“而且”的意思,前后条件需都成立 |
-o或|| | 逻辑或,“或者”的意思,只需前后条件中一个成立 |
! | 逻辑否 |
[ 表达式1 ] && [ 表达式2 ] [ 表达式1 -a 表达式2 ] [[ 表达式1 && 表达式2 ]] #且,要求前后表达式条件都成立
[ 表达式1 ] || [ 表达式2 ] [ 表达式1 -o 表达式2 ] [[ 表达式1 || 表达式2 ]] #或,只需前后表达式条件成立一个即可
[ 表达式1 ] || 命令1 #如果表达式1成立不会执行或运算符后面的命令1,如果表达式1条件不成立则会执行或运算符后面的命令1
[ 表达式1 ] && 命令1 || 命令2 #如果表达式1条件成立则执行命令1,如果表达式1条件不成立则会执行命令2[[ 99+1 -eq 100 ]] #若进行数学运算则需多加[]
[ ! 表达式1 ] #取反,如果表达式1条件成立则最终结果为条件不成立
- 案例ping方式判断目标主机是否存活
vim ping.sh
#!/bin/bash
IP=$1
ping -c 3 -i 0.5 -W 2 $IP &> /dev/null && echo "$IP online" || echo "$IP off"
-c | 发送包的个数 |
-i | 发送包的间隔时间 |
-W | 超时时间 |
-w | 多少秒后停止 ping 命令操作 |
- 案例判断服务状态
vim XXX.sh
#!/bin/bash
NUM=${ps -elf | grep 进程名 | grep -v "grep" | grep -v "$$" | wc -l} #$$代表脚本进程
[ $NUM -gt 0 ] && echo '进程名 is starting' || systemctl start 进程名
补充:判断进程是否正在运行的方法
systemctl status 进程服务
netstat -lntup | grep :端口/进程名
ss -lntup | grep :端口/进程名
lsof -i :端口
ps -elf | grep 进程名 | grep -v "grep" | grep -v "$$" | wc -l
pidof 进程名 | wc -w
killall -0 进程名
二、if语句的结构
-
单分支结构
等效于
[ 条件表达式 ] && 命令
- 案例已用磁盘空间
vim XXX.sh
#!/bin/bash
#总磁盘空间大小
total=$(df | grep -w / | awk '{print $2}' )
#已使用的磁盘空间大小
used=$(df | grep -w / | awk '{print $3}' )
#磁盘使用率百分比
percent=$(echo "scal=2;${used}/${total}*100" | bc | awk -F. '{print $1}')
if [ $percent -gt 80 ]
then
echo "警告!当前磁盘使用率已超过80%!使用率为${percent}%"
fi
chmod +x XXX.sh
bash XXX.sh
-
双分支结构
等效于·
[ 条件表达式 ] && 命令1 || 命令2
- 案例端口监听
vim XXX.sh
#!/bin/bash
#netstat -lntp | grep :端口号
#ss -lntp |grep :端口号
losf -i :端口号 &> /dev/null
if [ $? -eq 0 ]
then
echo "服务已在运行!"
else
echo "正在启动服务..."
systemctl start 服务名
fi
chmod +x XXX.sh
bash XXX.sh
-
多分支结构
- 案例分数对应惩处
vim XXX.sh
read -p "请输入你的分数:" score
if [ $score -eq 100 ]
then echo "..."
elif [ $score -ge 90 -a $score -lt 100 ]
then echo "..."
elif [ $score -ge 70 -a $score -le 89 ]
then echo "..."
else
echo "..."
fi
chmod +x XXX.sh
bash XXX.sh
- 案例判断数字是否为整数,是整数的话再判断为奇数还是偶数
vim XXX.sh
#!/bin/bash
read -p "请输入一个数字:" NUM
#整数%1为0,非整数则不为0
INT=$(echo "$NUM % 1" | bc)
#判断是否为整数
if [ "$INT" == "0" ];then
echo "$NUM 为整数"
#判断是否为0
if [ $NUM -eq 0 ];then
echo "0不是奇数也不是偶数"
else
a=$[NUM % 2]
#判断除以2的余数是否为0,0为偶数,不为0为奇数
if [ $a -eq 0 ];then
echo "$NUM 为偶数"
else
echo "$NUM 为奇数"
fi
fi
else
echo "${NUM}不为整数"
fi
chmod +x XXX.sh
bash XXX.sh
三、case语句结构
- 案例分数对应惩处
vim XXX.sh
#!/bin/bash
read -p "请输入你的分数:" score
case $score in
100)
echo "..."
;;
9[0-9])
echo "..."
;;
[78][0-9])
echo "..."
;;
[0-9]|[1-6][0-9])
echo "..."
*)
echo "..."
esac
chmod +x XXX.sh
bash XXX.sh