通过博文Shell脚本应用(一),可以在简单的Shell脚本程序中,各类语句将按先后顺序依次执行,从而实现批处理的自动化过程,然而,单一的顺序结构使得脚本国语机械化,不够“智能”,难以处理更加灵活的系统任务。

今天我们将认识并掌握如何进行条件测试操作,并通过正确使用if语句,使Shell脚本具有一定的“判断”能力,以根据不同的条件来完成不同的管理任务。

一、条件测试操作

要使Shell脚本具有一定的“智能”,面临的第一个问题就是如何区分不同的情况已确定执行何种操作。例如:当磁盘使用率达到某个点时,发出警告信息等操作。

Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时,表示成功;当返回值为非0时,则表示失败。使用专门的测试工具——test命令,可以对特定条件进行测试。

使用test测试命令时,两种语法:

格式1:test  条件表达式

或者

格式2:[  条件表达式  ]

这两种方式的作用完全相同,但通常第二种语法格式较为适用。
但是需要注意:第二种语法格式中括号“[ 条件表达式 ]”与条件表达式至少需要一个空格进行分隔!

根据需要测试的条件类型不同,条件表达式也不同,比较常用的条件操作包括:

1.文件测试

文件测试指的是根据特定的路径,判断对应的文件是目录还是文件,或者是否可读、可写、可执行等操作。常用的选项有:

-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)

执行条件测试操作以后,通过预定义变量$?来获得测试命令的返回值,从而判断该条件是否成立。比如:

[root@localhost ~]# [ -d /mnt ]              //测试/mnt是不是一个目录
[root@localhost ~]# echo $?                //查看前一条命令的返回值
0                                                           //0表示条件成立,非0则表示条件不成立

为了更直观的查看测试效果,可以结合“&&”和“echo”命令一起使用。比如:

[root@localhost ~]# [ -d /etc ] && echo "yes"
yes                 //输出“yes”表示条件成立,不输出“yes”则表示条件不成立

2.整数值比较

整数值比较指的是根据给定的两个整数值,判断第一个数与第二个数的关系,比如等于、大于、小于等。常用的选项有:

-eq:等于(Equal)
-ne:不等于(Not Equal)
-gt:大于(Greater Than)
-lt:小于(Lesser Than)
-le:小于或等于(Lesser or Equal)
-ge:大于或等于(Greater or Equal)

整数值比较在Shell甲苯编写中的应用较多。例如,用来判断已登录用户数量、开启的进程数等。比如:

[root@localhost ~]# A=`who | wc -l`
[root@localhost ~]# [ $A -eq 3 ] && echo "nice"
nice            //查看当前登录用户为3的话输出“nice”

3.字符串比较

字符串比较通常用力啊检查用户输入、系统环境等是否满足条件,在提供交互式操作的脚本中,也可以用来判断用户输入的位置参数是否符合要求。常用的参数有:

=:字符串内容相同
!=:字符串内容不同,! 号表示相反的意思
-z:字符串内容为空

语法格式:

[  字符串1  =  字符串2 ]
[  字符串1  !=  字符串2 ]
[  -z  字符串 ]

4.逻辑测试

逻辑测试指的是判断两个或多个条件之间的依懒关系。当系统任务取决于多个不同的条件时,根据这些条件是否同时成立或其中一个成立等情况,需要有一个测试过程,常用的参数有:

-a或&&:逻辑与,“而且”的意思;
-o或||:逻辑或,“或者”的意思;
!:逻辑否,“取反”的意思;

语法格式:

格式1:[  表达式1  ]  操作符  [  表达式2  ]  ... 
格式2:命令1  操作符  命令2  ... 

二、使用if语句结构

通过刚才的条件测试可以完成简单的判断并执行相应的曹组,但是当需要选择执行的命令语句较多时,这种方式会使代码显得复杂且不好理解。我们可以适当的使用if语句,来整理脚本结构,使得层次分明、清晰易懂。

1)if语句的结构

在Shell脚本应用中,if语句是最常用的一种流程控制方式,用力啊根据特定的条件测试结果,分别执行不同的操作(如果……那么……)。根据不同的复杂程度,if语句的选择结构可以分为三种基本类型,适用于不同的应用场合。

1.单分支if语句

if语句的:“分支”指的是不同测试结果所对应的执行语句(一条或多条)。对于if但分支的选择结构,只有在“条件成立”时才会执行相应的代码,否则不执行任何操作。

1)单分支if语句的语法结构:

if 
条件测试操作
then 
命令序列
fi

语句结构中,条件测试操作可以是“[ 条件表达式 ]”语句,也可以是其他可指定的命令语句,命令序列指的是一条或多条可执行的命令行,也包括嵌套使用的if语句或其他流程控制语句。

2)单分支if语句的流程图:

Shell脚本应用(二)_第1张图片

3)单分支if语句应用示例:

[root@localhost ~]# vim a.sh                            //随便定义脚本名称
#!/bin/bash                                                       //声明使用什么Shell
A="/mnt/cdrom"                                               //定义变量
if                                                                       //关键字(如果)
[ !-d $A ]                                                 //$A变量不是一个目录的话
then                                                                  //关键字(那么)
mkdir -p $A                                              //创建这个变量所对应的目录
fi                                                                      //关键字(结束)
[root@localhost ~]# sh a.sh                            //执行脚本
[root@localhost ~]# ll /mnt                               
总用量 0
drwxr-xr-x. 2 root root 6 7月  30 12:19 cdrom                //验证效果

2.多分支if语句

对于多分支的选择结构,要求针对“条件成立”、“条件不成立”两种情况分别执行不同的操作。

1)双分支if语句的语法结构:

if 
条件测试操作
then 
命令序列1
else 
命令序列2
fi

2)双分支if语句流程图:

Shell脚本应用(二)_第2张图片

3)双分支if语句应用示例:

[root@localhost ~]# vim b.sh
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &>/dev/null            //检查目标主机是否可以连通
if                                                                //关键字(如果)
[ $? -eq 0 ]                                        //测试上一条命令的返回结果
then                                                          //关键字(那么)
echo "Host $1 is up"
else                                                          //关键字(否则)
echo "Host $1 is down"
fi                                                              //关键字(结束)
#(注释)代码中,为了提高ping命令的测试率,使用“-c”表示只发送三个测试包;“-i”表示间隔时间为0.2秒;“-W”表示超时时间3秒。另外使用 “ &>  /dev/null”屏蔽ping命令执行过程的输出信息。
[root@localhost ~]# sh b.sh  192.168.1.1            
Host 192.168.1.1 is down                                         //执行脚本测试返回结果

3.多分支if语句

由于if语句可以根据测试结果的成立、不成立分别进行操作,所以能够嵌套使用,进行多次判断。

1)多分支if语句语法结构:

if  
条件测试操作1
then  
命令序列1
elif  
条件测试操作2 
then  
命令序列2
else
命令序列3
fi

2)多分支if语句流程图:

Shell脚本应用(二)_第3张图片

3)多分支if语句应用示例:

(1) 应用示例(一)
[root@localhost ~]# vim c.sh
#!/bin/bash
read -p "请输入您的分数(0——100):" A
if
[ $A -ge 85 ] && [ $A -le 100 ]                       //85~100分,优秀
then
echo "$A分,优秀!"
elif
[ $A -ge 70 ] && [ $A -le 84 ]                        //70~84分,及格
then
echo "$A分,及格!"
else
echo "$A分,不及格!"                               //其他分数,不及格
fi
[root@localhost ~]# sh c.sh 
请输入您的分数(0——100):66
66分,不及格!
[root@localhost ~]# sh c.sh 
请输入您的分数(0——100):79
79分,及格!
[root@localhost ~]# sh c.sh 
请输入您的分数(0——100):99
99分,优秀!
//验证执行脚本效果
(2)应用示例(二)

示例要求:
(1)使用df命令提取出根分区的磁盘占用率,赋值给变量DUG。
(2)使用mpstat命令提取CPU使用率(需安装sysstat软件包),赋值给变量CUG。
(3)使用free命令提取出内存使用率,赋值给变量MUG。
(4)判断上述监控项目是否超标,将需要告警的信息保存到/tmp/alert.txt文件。
(5)判断/tmp/alert.txt文件是否存在,若存在则作为告警邮件发送。

[root@localhost ~]# vim 1.sh
#!/bin/bash
# 提取性能监控指标(磁盘占用、CPU使用、内存使用)
DUG=$(df -hT | grep "/$" | awk '{print $6}' | awk -F% '{print $1}')
CUG=$(expr 100 - $(mpstat | tail -1 | awk '{print $12}' | awk -F. '{print $1}'))
MUG=$(expr $(free | grep "Mem:" | awk '{print $3}') \* 100 / $(free | grep "Mem:" | awk '{print $2}'))
# 设置告警日志文件、告警邮箱
ALOG="/tmp/alert.txt"
AMAIL="root"
# 判断是否记录告警
if [ $DUG -ge 0 ]
then
echo "磁盘占用率:$DUG %" >> $ALOG
fi
if [ $CUG -ge 0 ]
then
echo "CPU使用率:$CUG %" >> $ALOG
fi
if [ $MUG -ge 0 ]
then
echo "内存使用率:$MUG %" >> $ALOG
fi
# 判断是否发送告警邮件,最后删除告警日志文件
if [ -f $ALOG ]
then
cat $ALOG | mail -s "Host Alert" $AMAIL
rm -rf $ALOG
fi
[root@localhost ~]# sh 1.sh 
[root@localhost ~]# mail                             //查看邮件
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 1 message 1 new
N  1 root                  Tue Jul 30 13:01  20/662   "Host Alert"
& 
……………………                     //省略部分内容
磁盘占用率:26 %
CPU使用率:1 %
内存使用率:18 %                                  //验证结果
#(注释)实验环境,大于等于0就发送邮件,实际生产环境视情况而定!

也可以这样查看邮件:


[root@localhost ~]# cat /var/spool/mail/root
……………                  //省略部分内容
磁盘占用率:26 %
CPU使用率:1 %
内存使用率:18 %

您在 /var/spool/mail/root 中有邮件