Shell脚本之条件语句
文章目录
一、条件测试
1.test命令
测试特定表达式的成立与否,成立返回0,返回非零值则不成立
格式1:test 条件表达式
格式2:[ 条件表达式 ]
注意:条件表达式两边和中括号之间至少要有一个空格
2.文件测试
测试文件或目录相关属性或是否拥有相应权限
[ 操作符 文件或目录 ]
常用的测试操作符
操作符 | 功能/作用 |
---|---|
-d | 测试是否为目录(Directory) |
-e | 测试目录或文件是否存在(Exist) |
-f | 测试是否为文件(File) |
-r | 测试当前用户是否有权限读取(Read) |
-w | 测试当前用户是否有权限写入(Write) |
-x | 测试当前用户是否有权限执行(eXcute) |
[root@localhost ~]#[ -d /mnt ] #测试是否为目录
[root@localhost ~]#echo $? #查看上一条命令的执行结果,返回值为0时表示结果为真
0
[root@localhost ~]#ls
anaconda-ks.cfg home pjlx.sh survey.sh 文档
backup-2020-12-20.tgz initial-setup-ks.cfg prj.sh test31 下载
cal1.sh jc.sh pxsb.sh test34 音乐
cal.sh kyzjsjx.sh pxsbx.sh 公共 桌面
ddysjx.sh lx.sh qq.sh 模板
dysjx.sh mybak.sh sum1.sh 视频
first.sh path1.sh sum.sh 图片
[root@localhost ~]#[ -f first.sh ] #测试first.sh是否为文件
[root@localhost ~]#echo $? #查看上一条命令的执行结果,返回值为0时表示结果为真
0
[root@localhost ~]#[ -d first.sh ] #测试first.sh是否为目录
[root@localhost ~]#echo $? #查看上一条命令的执行结果,返回值为0时表示结果为真
1
[root@localhost ~]#[ -r first.sh ] #测试first.sh是否有读取权限
[root@localhost ~]#echo $? #查看上一条命令的执行结果,返回值为0时表示结果为真
0
[root@localhost ~]#[ -f first.sh ] && echo "yes"
yes #测试first.sh是否为文件,满足条件时输出yes
3.整数值比较
格式
[ 整数1 操作符 整数2 ]
常用比较操作符
操作符 | 作用/功能 |
---|---|
-eq | 等于(Equal) |
-ne | -ne:不等于(Not Equal) |
-gt | -gt:大于(Greater Than) |
-lt | -lt:小于(Lesser Than) |
-le | -le:小于或等于(Lesser or Equal) |
-ge | -ge:大于或等于(Greater or Equal) |
[root@localhost ~]#free -m #查看内存使用情况,以MB为单位
total used free shared buff/cache available #总物理内存为1823MB #空闲内存为1116MB
Mem: 1823 305 1116 9 401 1308
Swap: 4095 0 4095
[root@localhost ~]#free -m | grep "Mem" | awk '{print $4}'
1116 #以MB为单位查看内存,筛选出Mem那行,并打印出第四列内容到屏幕上
[root@localhost ~]#freemem=$(free -m | grep "Mem" | awk '{print $4}')
[root@localhost ~]#echo $freemem
1116 #把以上那段得出的结果赋值给freemem,然后查看其变量值
[root@localhost ~]#[ $freemem -gt 1024 ] && echo "$freemem"MB
1116MB #如果变量值大于1024,输出其变量值MB,""之中可引用其他变量,此处也用作分隔后面字符
4.浮点运算
1)bc:内建bash计算器
bash不支持浮点运算,只支持整数运算,这是个巨大的限制,如果需要进行浮点运算,需要借助bc(内建bash计算器)或awk处理。
输入bc回车进入计算器,输入quit回车或直接Ctrl D退出计算器。
[root@localhost ~]#bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
12 * 2.4
28.8
2.4 * (2 + 9)
26.4
quit
2)引用bc
包括加减乘除
[root@localhost ~]#v1=$(echo "2.4*2"|bc)
[root@localhost ~]#echo $v1
4.8
[root@localhost ~]#v2=$(echo "3.6/1.5"|bc)
[root@localhost ~]#echo $v2
2
[root@localhost ~]#v2=$(echo "scale=3; 3.6/1.5"|bc)
[root@localhost ~]#echo $v2 #scale=3表示输出结果包含3位小数
2.400
[root@localhost ~]#v3=$(echo "3.6+1.5"|bc)
[root@localhost ~]#echo $v3
5.1
[root@localhost ~]#v3=$(echo "3.6-1.5"|bc)
[root@localhost ~]#echo $v3
2.1
3)awk:简便的数据处理工具
awk适合处理小型的文本数据,其格式:
awk '条件类型1 {操作1} 条件类型2 {操作2} ...' filename
利用awk做加减乘除:
#加法
[root@localhost ~]#f=$(awk 'BEGIN{print 3.6+1.5 }')
[root@localhost ~]#echo $f
5.1
[root@localhost ~]#echo "3.6+1.5=$f"
3.6+1.5=5.1
#减法
[root@localhost ~]#v4=$(awk 'BEGIN{print 3.6-1.5 }')
[root@localhost ~]#echo "3.6-1.5=$v4"
3.6-1.5=2.1
#乘法
[root@localhost ~]#v4=$(awk 'BEGIN{print 3.6*1.5 }')
[root@localhost ~]#echo "3.6*1.5=$v4"
3.6*1.5=5.4
#除法
[root@localhost ~]#v4=$(awk 'BEGIN{print 3.6/1.5 }')
[root@localhost ~]#echo "3.6/1.5=$v4"
3.6/1.5=2.4
利用awk分析处理数据
取出账号和登录者IP,且账号和IP之间用[Tab]隔开,如下
其中$1是账号,$3是IP
[root@localhost ~]#last -n 3 #利用last取出登录者数据,取出前三行
root pts/0 192.168.2.1 Wed Dec 23 13:28 still logged in
reboot system boot 3.10.0-693.el7.x Wed Dec 23 13:27 - 17:36 (04:09)
root pts/0 192.168.2.1 Tue Dec 22 08:34 - down (08:31)
wtmp begins Wed Nov 11 19:55:40 2020
[root@localhost ~]#last -n 3 | awk '{print $1 "\t" $3}'
root 192.168.2.1
reboot boot
root 192.168.2.1
wtmp Wed
5.字符串比较
1)格式
格式1:[ 字符串1 = 字符串2 ]
[ 字符串1 != 字符串2 ]
格式2: [ -z 字符 ]
2)常用的测试操作符
=:字符串内容相同
!=:字符串内容不同, !号表示相反的意思
-z:字符串内容为空
-n:检测字符串是否存在
For example:
[root@localhost ~]#ABC=123
[root@localhost ~]#echo $ABC
123
[root@localhost ~]#[ $ABC = 123 ] && echo "成立" #判断ABC的值是否和字符串123相同,相同输出“成立”
成立
[root@localhost ~]#[ $ABC != 123 ] && echo "成立" || echo "不成立"
不成立 #||逻辑或,上一条命令执行失败的时候执行后面的命令
6.逻辑测试
1)格式
格式1:[ 表达式1 ] 操作符 [ 表达式2 ]
格式2:命令1 操作符 命令2
2)常用的测试操作符
操作符 | 功能/作用 |
---|---|
-a或&& | 逻辑与,而且的意思 |
-o或|| | 逻辑或,或者的意思 |
! | 逻辑否 |
注:①同一个括号内用-a或-o,两个括号间用&& 或||
②&&、||操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[]结构中的话,会报错
③操作符和两边表达式之间必须要有至少一个空格,否则会报错
For example:
a=3
[ $a -ne 1 ] && [$a != 2 ]等同于 [ $a -ne 1 -a $a != 2 ]
[[ $a != 1 && $a != 2 ]]
[[ 5 -lt 9 ]] && echo "true" || echo "false"
[[ 3 -ge 5 ]] && echo "true" || echo "false"
[root@localhost ~]#[ $a -ne 1 ] && [ $a !=2 ] #=和2之间无空格导致报错
-bash: [: 3: 期待一元表达式
[root@localhost ~]#[ $a -ne 1 ] && [ $a != 2 ]
[root@localhost ~]#a=3
[root@localhost ~]#[ $a -ne 1 ] && [ $a != 2 ] #判断a的值不等于1且不等于2
[root@localhost ~]#echo $? #上一个命令成立返回0,不成立返回其他值
0
[root@localhost ~]#[[ $a != 1 && $a != 2 ]]
[root@localhost ~]#echo $?
0
[root@localhost ~]#[[ 5 -lt 9 ]] && echo "true" || echo "false"
true #判断5是否小于9,成立时输出true,||前面的不成立时输出false
[root@localhost ~]#[[ 3 -ge 5 ]] && echo "true" || echo "false"
false #判断3是否大于或等于5,成立输出true,||前面不成立时输出false
二、if语句
1.单分支结构
if 条件测试操作
then
命令序列
fi
- 三种表达方式
if [ 3 -gt 2 ]
then
echo "ok"
fi
if [ 3 -gt 2 ];then echo "ok";fi
[ 3 -gt 2 ] && echo "ok"
2.双分支if语句
if 条件测试操作
then
命令序列1
else
命令序列2
fi
For example:
[root@localhost ~]#vim ping.sh
[root@localhost ~]#chmod +x ping.sh
[root@localhost ~]#./ping.sh 192.168.100.100
192.168.100.100 off
[root@localhost ~]#./ping.sh 192.168.2.3
192.168.2.3 online
[root@localhost ~]#cat ping.sh
#!/bin/bash
ping -c 3 -i 0.5 -W 2 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "$1 online"
else
echo "$1 off"
fi
-c:发送包的个数
-i:发送包测间隔时间
-w:超时时间
发三个包,间隔0.5秒,超时时间为2秒,未超时把所有输出信息扔到黑洞文件,执行成功时$?=0,就输出此IP在线即online
否则2秒超时后就丢尽黑洞文件并且输出IP已关闭off
3.多分支if语句
if 条件测试操作1
then
命令序列1
elif 条件测试操作2
then
命令序列2
else
命令序列3
fi
For example:
[root@localhost ~]#vim chengji.sh
[root@localhost ~]#cat chengji.sh
#!/bin/bash
#
read -p "请输入您的分数(1-100): " score
if [ $score -ge 85 ] && [ $score -le 100 ]
then
echo "优秀!"
elif [ $score -ge 75 ] && [ $score -le 84 ]
then
echo "还不错,继续努力!"
elif [ $score -ge 60 ] && [ $score -le 74 ]
then
echo "及格,还需加油!"
elif [ $score -ge 1 ] && [ $score -le 59 ]
then
echo "没及格,在错误中进步,你可以的!"
fi
[root@localhost ~]#chmod +x chengji.sh
[root@localhost ~]#./chengji.sh
请输入您的分数(1-100): 98
优秀!
[root@localhost ~]#./chengji.sh
请输入您的分数(1-100): 83
还不错,继续努力!
[root@localhost ~]#./chengji.sh
请输入您的分数(1-100): 70
及格,还需加油!
[root@localhost ~]#./chengji.sh
请输入您的分数(1-100): 52
没及格,在错误中进步,你可以的!
三、case语句
1.case多分支结构
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
.....
*)
默认命令序列
esac
注意:
- case行尾必须为单词"in",每一模式必须以右括号")"结束。
- 双分号";;"表示命令序列的结束。
- 模式字符串中,可以用方括号表示一个连续的范围,如"[0-9]";还可以用竖杠符号"|“表示或,如"AIB”
- 最后的")"表示默认模式,其中的相当于通配符。
2.实例
For example:
[root@localhost ~]#vim chengjicase.sh
[root@localhost ~]#cat chengjicase.sh
#!/bin/bash
read -p "请输入您的分数(0-100) : " score
if [ $score -le 100 -o $score -ge 0 ];then
[[ $score -ge 80 && $score -le 100 ]] && a="great"
[[ $score -ge 60 && $score -lt 80 ]] && a="standard"
[[ $score -ge 0 && $score -lt 60 ]] && a="false"
case $a in
great)
echo " $score分,优秀! "
;;
standard)
echo " $score分,合格! "
;;
false)
echo " $score分,不合格! "
;;
*)
echo "输入有误!"
esac
fi
[root@localhost ~]#chmod +x chengjicase.sh
[root@localhost ~]#./chengjicase.sh
请输入您的分数(0-100) : 98
98分,优秀!
[root@localhost ~]#./chengjicase.sh
请输入您的分数(0-100) : 78
78分,合格!
[root@localhost ~]#./chengjicase.sh
请输入您的分数(0-100) : 52
52分,不合格!
[root@localhost ~]#./chengjicase.sh
请输入您的分数(0-100) : 111
输入有误!