1、条件测试表达式
1.1 shell的条件测试
条件测试,作用是验证条件是否符合预期。以下是常用语法
针对以上表有几个注意事项需要说明:
语法1中的test命令和语法2中的[]是等价的。语法3中的[[]]为扩展的test命令,语法4中的(())命令常用于计算,建议在生产环境中使用相对友好的语法2,即中括号[]的语法
在双中括号[[]]中可以使用通配符(如*)等进行模式匹配,这是区别于其他几种语法的地方
&&、||、>、<等操作符可以应用到[[]]中,但不能应用于[]中,在[]中一般用-a、-o、-gt、-lt取代
对于整数的关系运算,也可以使用Shell的算术运算符(())
条件测试简单语法示例
-
test条件测试语句示例
-
[]条件测试语句示例
特殊的条件测试表达式语句,可以执行多个命令
[ 条件1 ] && {
命令1
命令2
...
}
[[ 条件1 ]] && {
命令1
命令2
...
}
test 条件1 && {
命令1
命令2
...
}
1.2 文件测试表达式
练习:以脚本传参和read读入的方式输入两个文件路径,任意一个文件不存在,则提示用户第几个文件不存在,并退出脚本
[root@shell-project /server/scripts]# cat tiaojian.sh
#!/bin/bash
read -p "请输入两个文件名称: " vars1 vars2
[ -f "$vars1" ]&&{
echo $vars1
} ||{
echo "第一个文件不存在"
exit
}
[ -f "$vars2" ]&&{
echo $vars2
} ||{
echo "第二个文件不存在"
exit
}
[root@shell-project /server/scripts]# sh tiaojian.sh
请输入两个文件名称: aa.txt test.sh
第一个文件不存在
1.3 字符串测试表达式
字符串测试表达式的作用:比较两个字符是否相同、测试字符串的长度是否为0、字符串是否为NULL等,常用的字符串操作符如下所示:
注意:对于字符串测试的时候,一定要把字符串加双引号
作业:
在“在使用脚本传参的方式实现整数的加、减、乘、除、取余、幂运算”此作业的基础上,对传入的参数或者read读入的变量内容进行判断,如果不符合计算条件,提示用户,并退出,不要用if判断
分析:
1>传入的参数个数必须为两个
2>传入的两个参数必须为整数
3>在除法中,除数不能为0
[root@shelledu /server/scripts]# cat jisuanqi.sh
#!/bin/bash
read -p "请输入需要计算的内容: " m n
# 判断传参是否为整数
expr $m + $n + 1 &> /dev/null
[ "$?" != "0" ] && {
echo "参数必须为整数"
exit 2
}
echo -n "$m+$n="; echo $(($m+$n))
echo -n "$m-$n="; echo $(($m-$n))
echo -n "$m*$n="; echo $(($m*$n))
echo -n '幂运算: '; echo $(($m**$n))
# 判断除数是否为0
[ "$n" = "0" ] && {
echo "除数必须不能为0!!!"
exit 3
}
echo -n "$m/$n="; echo $(($m/$n))
echo -n "$m%$n="; echo $(($m%$n))
[root@shelledu /server/scripts]# sh jisuanqi.sh
请输入需要计算的内容: 20 5
20+5=25
20-5=15
20*5=100
幂运算: 3200000
20/5=4
20%5=0
[root@shelledu /server/scripts]#
1.4 整数二元比较操作符
注意:不推荐使用[[]]比较数字,因为在大小比较中,[[]]比较的是字符串的arscII码
有关[]、[[]]、(())用法小结:
- 整数加双引号比较也可以
- [[]]中使用类似-eq的写法是正确的,而[[]]中用类似>、<的写法也可能不对,有可能值比较第一位,原因在于arscII码的特殊性
- [[]]中用类似>、<的写法语法没错(经过转义),但是逻辑结果不对,使用=、!=可以正确比较
- (())中不能使用类似-eq的写法,可以使用类似>、<、==(=不可以)的写法
推荐:在比较数字的时候推荐使用[]和-gt、-lt等类似的搭配,或者使用(())和>、<等搭配
1.4.1 小练习:
1>查看当前磁盘/当前状态,如果使用率超过3%,则触发报警发邮件
[root@shelledu /server/scripts]# cat test3-4-1-1.sh
#!/bin/bash
#查看当前磁盘/当前状态,如果使用率超过11%,则触发报警发邮件
sda_bf=`df -h |awk 'NR==2{print $5}'`
sda=${sda_bf%\%*}
[ $sda -gt 11 ]&&{
echo $sda_bf
echo '当前磁盘的使用率已超过11%.'| mail -s '磁盘不足' wwjsqflymail@163.com
exit 0
}
[root@shelledu /server/scripts]# sh test3-4-1-1.sh
12%
[root@shelledu /server/scripts]#
2>查看内存使用状况,如果占用超过10%,则触发报警
[root@shelledu /server/scripts]# cat test3-4-1-2.sh
#!/bin/bash
#查看内存使用状况,如果占用超过5%,则触发报警
#total_mem=`free |awk 'NR==2{print $2}'`
#used_mem=`free |awk 'NR==2{print $3}'`
#bfb=`echo "scale=2;$used_mem/$total_mem*100"|bc`
bfb=`free |awk 'NR==2{print $3/$2*100}'`
sub_bfb=${bfb%.*}
echo $sub_bfb
[ $sub_bfb -gt 5 ]&&{
echo '内存使用率已超过5%'|mail -s '内存快满了' wwjsqflymail@163.com
}
[root@shelledu /server/scripts]# dd if=/dev/zero of=/tmp/aaa.txt bs=100M count=100 #模拟环境
[root@shelledu /server/scripts]# sh test3-4-1-2.sh
10
[root@shelledu /server/scripts]#
1.5 逻辑操作符
小练习:
1>输入或者通过命令传入一个字符或者数字,如果传入的数字等于1就打印1,如果等于2就打印2;如果不等于1也不等于2,就提示输入不对,然后退出程序。(两种比较方式任选其一:数字比较或字符串比较)
[root@shell-project /server/scripts]# cat test04.sh
#!/bin/bash
#输入或者通过命令传入一个字符或者数字,如果传入的数字等于1就打印1,如果等于2就打印2;如果不等于1也不等于2,就提示输入不对,然后退出程序。(两种比较方式任选其一:数字比较或字符串比较)
read -p "请输入内容: " num
[ "$num" = "1" -o "$num" = "2" ]&&{
echo $num
}||{
echo '抱歉,输入的内容不对!!!'
exit
}
[root@shell-project /server/scripts]# sh test04.sh
请输入内容: 2
2
[root@shell-project /server/scripts]# sh test04.sh
请输入内容: 1
1
[root@shell-project /server/scripts]# sh test04.sh
请输入内容: er
抱歉,输入的内容不对!!!
2>开发shell脚本,分别以脚本传参方式和read读入方式比较两个整数大小,用条件表达式(禁止if)进行判断并以屏幕输出的方式提醒用户比较结果。(一共需要开发2个脚本,在传参和read读入方式实现时,需要对变量是否为数字及传参个数是否正确给予提示)
分析:
- 判断是否是两个参数,(通过read不需要判断)
- 判断是否为整数(使用expr计算,出返回值,判断返回值$?是否是0)
- 比较大小,分为三个阶段:大于、等于、小于
\\方法一:通过传参的方式
[root@shell-project /server/scripts]# cat test06.sh
#!/bin/bash
#开发shell脚本,分别以脚本传参方式和read读入方式比较两个整数大小,用条件表达式(禁止if)进行判断并以屏幕输出的方式提醒用户比较结果。(一共需要开发2个脚本,在传参和read读入方式实现时,需要对变量是否为数字及传参个数是否正确给予提示)
[ $# -ne 2 ]&&{
echo '必须输入两个参数!'
exit
}
expr $1 + $2 >/dev/null 2>&1
[ $? -ne 0 ]&&{
echo '输入的参数必须是整数!'
exit
}
[ $1 -gt $2 ]&&{
echo "$1大于$2"
}
[ $1 -eq $2 ]&&{
echo "$1等于$2"
}
[ $1 -lt $2 ]&&{
echo "$1小于$2"
}
[root@shell-project /server/scripts]# sh test06.sh 2 f
输入的参数必须是整数!
[root@shell-project /server/scripts]# sh test06.sh 2 3
2小于3
[root@shell-project /server/scripts]# sh test06.sh 4 3
4大于3
[root@shell-project /server/scripts]# sh test06.sh 4 4
4等于4
[root@shell-project /server/scripts]#
\\方法二:通过read
[root@shell-project /server/scripts]# cat test06-read.sh
#!/bin/bash
#开发shell脚本,分别以脚本传参方式和read读入方式比较两个整数大小,用条件表达式(禁止if)进行判断并以屏幕输出的方式提醒用户比较结果。(一共需要开发2个脚本,在传参和read读入方式实现时,需要对变量是否为数字及传参个数是否正确给予提示)
read -p '请输入要比较的两个参数:' n m
expr $n + $m >/dev/null 2>&1
[ $? -ne 0 ]&&{
echo '输入的参数必须是整数!'
exit
}
[ $n -gt $m ]&&{
echo "$n大于$m"
}
[ $n -eq $m ]&&{
echo "$n等于$m"
}
[ $n -lt $m ]&&{
echo "$n小于$m"
}
[root@shell-project /server/scripts]#
3>打印菜单,按照选择项选择你喜欢的美女
示例菜单:
1.heijiajia
2.gaoyuanyuan
3.caixukun
please input the num you like:
要求:
1)当用户输入1时,输出“I guess you like heijiajia”,然后退出脚本
2)当用户输入非1-3的字符时,输出“I guess you are not man”,然后退出脚本
[root@shell-project /server/scripts]# cat test05.sh
#!/bin/bash
#打印菜单,按照选择项选择你喜欢的美女
cat <<EOF
1.heijiajia
2.gaoyuanyuan
3.caixukun
EOF
read -p "please input the num you like: " num
[ $num -eq 1 -o $num -eq 2 -o $num -eq 3 ]&&{
[ $num -eq 1 ]&&{
echo 'I guess you like heijiajia!'
exit 0
}
[ $num -eq 2 ]&&{
echo 'I guess you like gaoyuanyuan!'
exit 0
}
[ $num -eq 3 ]&&{
echo 'I guess you like caixukun!'
exit 0
}
}||{
echo 'I guess you are not man!'
exit 2
}
[root@shell-project /server/scripts]# sh test05.sh
1.heijiajia
2.gaoyuanyuan
3.caixukun
please input the num you like: 1
I guess you like heijiajia!
[root@shell-project /server/scripts]# sh test05.sh
1.heijiajia
2.gaoyuanyuan
3.caixukun
please input the num you like: 4
I guess you are not man!
1.6 案例实操
1.6.1 检查OSPF route-ID配置,配置如下,请用shell编写代码,条件如下:
1、 检查ospf的route-id值
2、 route-id值必须与interface LoopBack0的IP地址值相同
grep -A 1 "interface LoopBack0" 3.txt | sed -n '3}
3、 如果两个值不相等,或ospf的route-id值不以139开头,则打印出route-id的值
/server/txt/ospf.txt
ofpf 100
route-id 139.11.0.1
area 0.0.0.0
network 139.11.0.1 0.0.0.0
network 140.11.0.0 0.0.0.3
network 140.11.0.8 0.0.0.3
network 140.11.0.16 0.0.0.3
network 140.11.0.24 0.0.0.3
network 140.11.0.32 0.0.0.3
#
interface LoopBack0
ip address 139.11.0.1 255.255.255.255
#
思路:
1> 取出route-id的ip值IP1
2> 取出interface LoopBack0的ip值IP2
3> [[ ! $IP! = ~ ^139]]
[root@shell-project /server/scripts]# cat test07.sh
#!/bin/bash
#检查ospf的route-id值
route_id=`awk 'NR==2{print $2}' /server/txt/ospf.txt`
loop_ip=`grep -A 1 'interface LoopBack0' /server/txt/ospf.txt |awk 'NR==2{print $3}'`
#如果两个值不相等,或ospf的route-id值不以139开头,则打印出route-id的值
route_head=${route_id%%.*}
[ "$route_id" != "$loop_ip" -o $route_head -ne 139 ]&&{
echo ${route_id}
}|| {
echo 'route-id值与interface LoopBack0的IP地址值相同'
}
[root@shell-project /server/scripts]# sh test07.sh
route-id值与interface LoopBack0的IP地址值相同
1.6.2 处理以下文件内容,将域名提取并进行计数排序,如处理:
/server/txt/yuming.txt
http://www.baidu.com/index.html
http://www.baidu.com/1.html
http://post.baidu.com/index.html
http://mp3.baidu.com/index.html
http://www.baidu.com/3.html
http://post.baidu.com/2.html
得到如下结果:
域名的出现次数 域名
3 www.baidu.com
2 post.baidu.com
1 mp3.baidu.com
思路:
1> sds
2> history |cut -c 8-|sort |uniq -c|sort -rn|head
3> 排序公式,必须要会!!!
sort |uniq -c|sort -rn
[root@shell-project /server/scripts]# cat test09.sh
#!/bin/bash
#处理以下文件内容,将域名提取并进行计数排序
awk -F'/' '{print $3}' /server/txt/yuming.txt |awk '{a[$0]++}END{for(i in a)print a[i],i}'|sort -rn|sed '1i域名的出现次数 域名'
[root@shell-project /server/scripts]# sh test09.sh
域名的出现次数 域名
3 www.baidu.com
2 post.baidu.com
1 mp3.baidu.com
[root@shell-project /server/scripts]#
1.6.3 打印菜单,按照选择项一键安装不同的web服务
示例菜单:
1.[install lnmp]
2.[install lamp]
3.[exit]
please input the num you want:
要求:
1)当用户输入1时,输出“start installing lamp提示”,然后执行/server/scripts/lamp.sh,(执行方式使用全路径方式执行)。脚本内容输出“lamp is installed”并退出脚本,此为工作中的一键安装lamp脚本
2)当用户输入2时,输出“start installing lnmp提示”,然后执行/server/scripts/lnmp.sh, (执行方式使用全路径方式执行)。脚本内容输出“lnmp is installed”并退出脚本,此为工作中的一键安装lnmp脚本
3)当输出3时,退出当前菜单及脚本
4)当用户输入非1-3的字符时,输出“Input Error”,然后退出脚本
5)对执行的脚本进行相关的条件判断,例如:脚本是否存在,是否可执行等操作,尽量使用今天讲的知识点
[root@shell-project /server/scripts]# cat lamp.sh
#!/bin/bash
sleep 2
echo 'lamp is installed! '
[root@shell-project /server/scripts]# cat lnmp.sh
#!/bin/bash
sleep 2
echo 'lnmp is installed! '
[root@shell-project /server/scripts]#
[root@shell-project /server/scripts]# cat test08.sh
#!/bin/bash
#定义变量
lamp="/server/scripts/lamp.sh"
lnmp="/server/scripts/lnmp.sh"
#打印菜单
cat << EOF
1.[install lamp]
2.[install lnmp]
3.[exit]
EOF
#使用read读取输入
read -p 'please input the num you want: ' num
#由于数字比较方式输入英文的时候会报错,所以这里用字符串比较方式
[ "$num" = "1" -o "$num" = "2" -o "$num" = "3" ]&&{
[ "$num" = "1" ]&&{
echo 'start installing lamp……'
[ -f "$lamp" ]&&{
[ ! -x "$lamp" ]&&{
echo "$lamp没有执行权限,不可执行"
exit 1
}
$lamp
exit 0
}||{
echo "error: $lamp is not exist."
exit 1
}
}
[ "$num" = "2" ]&&{
echo 'start installing lnmp……'
[ -f "$lnmp" ]&&{
[ ! -x "$lnmp" ]&&{
echo "$lnmp没有执行权限,不可执行"
exit 1
}
$lnmp
exit 0
}||{
echo "error: $lnmp is not exist."
exit 1
}
}
[ "$num" = "3" ]&&{
echo 'good byb!'
exit 0
}
}||{
echo 'Input Error'
exit 1
}
[root@shell-project /server/scripts]#
[root@shell-project /server/scripts]# sh test08.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
please input the num you want: 1
start installing lamp……
lamp is installed!
[root@shell-project /server/scripts]#
网友评论