Shell中的流程控制语句(1)中服务语句

目录

什么是流量控制?

Shell中的流控语句分为:

1、单分支if条件语句

单分支条件语句是最简单的,即只有一个判断条件。如果满足条件,则执行程序,否则不执行任何操作。

语法如下:

<code class="language-shell">if[ 条件判断式 ];then
    程序
fi

单分支条件语句需要注意几点:

例子:

需求:根分区使用率超过80%时报警。

# 1.获取根分区使用率
# 1.1 通过df命令查看Linux系统上的文件系统磁盘使用情况。
#   df命令用于显示目前在Linux系统上文件系统磁盘使用情况的统计。
[root@localhost tmp]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        19G  2.1G   16G  12% /
tmpfs           491M     0  491M   0% /dev/shm
/dev/sda1       240M   34M  194M  15% /boot
# 1.2 把根分区的磁盘使用情况提取出来
[root@localhost tmp]# df -h | grep /dev/sda3
/dev/sda3        19G  2.1G   16G  12%  /
# 1.3 然后用awk命令,进行列信息提取,提取第五列。
[root@localhost tmp]# df -h | grep /dev/sda3 | awk '{print $5}'
12%
# 1.4 截取前面的数字部分,方便后边判断使用。
#   以%作为分隔符,然后提取1列。
[root@localhost tmp]# df -h | grep /dev/sda3 | awk '{print $5}' | cut -d "%" -f 1
12
# 2.编写Shell程序
# 2.1 创建一个Shell文件if1.sh
[root@localhost tmp]# vim if1.sh
# 编写内容如下:
#!/bin/bash

# 把根分区使用率作为变量值赋予变量rate
# 把上面的命令以命令行的方式先敲一遍,确认能获取到我们需要的内容。
# 如果在Shell里面直接写,会有很大难度。
rate=$( df -h | grep /dev/sda3 | awk '{print $5}' | cut -d "%" -f 1 )
# 判断rate的值如果大于等于80,则执行then后的程序。
# 我们这里为了有演示效果,把输出调整为10.
if [ $rate -ge 10 ]
        then
                # 打印警告信息。在实际工作中,也可以向管理员发送邮件。
                echo "Warning! /dev/sda3 is full !!!"
fi
# 上面的程序表示,如果根分区使用率超过80%则打印`Warning! /dev/sda3 is full !!!``,没有则什么都不做。
# 3. 给if1.sh文件赋予执行权限,并执行该脚本。
[root@localhost tmp]# chmod 755 if1.sh
[root@localhost tmp]# ./if1.sh
Warning! /dev/sda3 is full !!!

2、if 条件语句的双分支

语法:

if [ 条件判断式 ]
    then
        条件成立时,执行的程序
    else
        条件不成立时,执行的程序
fi

(1)示例1

让我们写一个数据备份的例子,看看if条件语句的双分支。

创建文件如果2.sh:

#!/bin/bash
# 需求:备份MySQL数据库

# 1.首先需要同步时间
# 因为我们的服务器上的时间可能会存在误差,
# 我们可以链接ntp时间服务器,来自动更新时间,
# 这样我们服务器上的时间就准确了,
# 下面一行命令是链接到亚洲的ntp时间服务器上,更新时间。
# 目的是保证所有服务器的时间是统一的。
ntpdate asia.pool.ntp.org &>/dev/null
# 提示:你也可以单独写一个脚本,专门用于时间同步。
# &>/dev/null:为把所有输出丢入垃圾箱(不想看到在何输出)
# &>:为无论正确输出还是错误输出,都输出到一个文件中。
# /dev/null类似是一个虚拟设备,或者是当成回收站,
# 任何信息丢进去,就会消失不见。
# 如果有不需要看的命令提示信息,就可以这样处理。
# 这是一个标准写法。
# 2.把当前系统时间按照“年月日”格式赋予变量date
# 默认的时间格式
# [root@localhost tmp]# date
# 2020年 10月 18日 星期日 10:28:27 CST
# 只取年月日,注意+和%之间不能有空格,否则命令会报错。
# [root@localhost tmp]# date +%y%m%d
# 201018
date=$(date +%y%m%d)
# 3.统计mysql数据库的大小,并把结果赋予size变量。
# 该数据主要是一个统计数据,没有多大作用,
# 只是为了写日志,告诉你今天备份的MySQL数据库的大小。
size=$(du -sh /var/1ib/mysql)
# 4.开始备份数据库
# 4.1 判断备份目录是否存在,是否为目录
if [ -d /tmp/dbbak ]
    then
        # 4.2如果判断为真,执行以下脚本
        # dbinfo.txt:数据库备份说明文件,内容就是在某年某月的某一天,备份了多大的数据。
        # 把当前日期写入文件
        echo "Date:$date!" 〉 /tmp/dbbak/dbinfo.txt
        # 把数据库大小写入文件

        echo "Data size:$size" >> /tmp/dbbak/dbinfo.txt
        # 4.3 进入到备份目录dbbak中
        cd /tmp/dbbak
        # 4.4 备份数据库
        # 把数据库数据和备份说明文件进行打包压缩为mysql-lib-$date.tar.gz
        # &>/dev/null:为把所有输出丢入垃圾箱(不想看到在何输出)
        tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
        # 4.5 删除备份说明文件
        rm -rf /tmp/dbbak/dbinfo.txt
    else
        # 4.6 如果判断为假,则建立备份目录
        mkdir /tmp/dbbak
        # 4.7 执行上边4.2到4.5的步骤
        # 把日期和数据库大小保存到备份说明文件
        echo "Date:$date!" 〉 /tmp/dbbak/dbinfo.txt
        echo "Data size:$size" >> /tmp/dbbak/dbinfo.txt
        # 压缩备份数据库与备份说明文件
        cd /tmp/dbbak
        tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
        # 删除备份说明文件
        rm -rf /tmp/dbbak/dbinfo.txt
fi

说明:

这种数据库备份方式不是很合理,主要是在命令行备份数据库,如下:

tar -zcf mysql-lib-$date.tar.gz /var/1ib/mysql dbinfo.txt &>/dev/nul1

不合理的原因包括:

注意:这只是一个数据库备份的练习,不能在工作中直接使用,但是思路就是这个思路,这里注意一下。

(2)示例 2

在实际工作中,服务器上的服务经常会宕机。以apache服务为例。如果我们没有很好地监控服务器,服务器中的服务就会中断,而管理员却不知道。发现之后,会有一定的延迟,直到管理员介入。这时候我们可以写一个脚本来监控这台机器的服务。如果服务停止或宕机,这些服务可以自动重启。

我们以apache服务为例:

在前提下,我们通过RPM包安装了apache服务并启动,如下图:

方法一:

分析脚本是如何实现的:

思路:取出80端口,赋值给一个变量,

判断变量的值是否为80,如果是,记录日志,如果不是,启动apache服务。

图片[1]-Shell中的流程控制语句(1)中服务语句-唐朝资源网

开始写:

创建文件如果3.sh:

#!/bin/bash
# 判断apache服务是否启动,如果没有启动则自动启动。
# 1.把80端口截取出来,赋值到一个变量中
port=$(netstat -tuln | awk '{print $4}' | grep ":80$")
# 2.判断port变量是否为空
if [ "$port" == "" ]
    then
        # 为空则证明apache服务没有启动
        # 发送邮件
        echo "apache httpd is down,must restart!"
        # 启动apache服务
        /etc/rc.d/init.d/httpd start &>/deb/null
        # 这里不建议使用service的方式启动apache服务,
        # service启动服务是一种快捷方式,
        # 有可能在脚本中会出问题,这里需要注意一下。
    else
        # 不为空则证明apache服务以启动
        # 可以记录日志
        echo "apache httpd is ok."
fi

注意:

不能使用grep “80”命令过滤数据,因为Shell中的正则表达式包含匹配,如808、8080等,会被匹配。

使用这个脚本:

提示:

脚本执行过程中,如果发现服务没有启动,会通知管理员,也可以通过命令直接重启apache服务。您无需管理员即可重新启动服务。管理员只要收到服务器出现问题的通知,就可以过来查看是什么原因。

方法二:

以上实现方式基本可以实现检测apache服务的需求。

但是在实际工作环境中,可能会出现这样的情况,比如apache服务正常,80端口也开放了,但是此时的访问量太大,apache服务直接拥挤出去。也就是说进程在,端口也(卡住),但是apache服务没有响应。这时候通过检查80端口,我们找不到服务器中apache服务的问题。

让我们先学习一个命令:

nmap 命令是一个端口扫描命令。命令格式如下:

[root@localhost ~]# nmap -sT 域名或 IP
选项:
    -s:扫描。
    -T:扫描所有开启的TCP端口。

图片[2]-Shell中的流程控制语句(1)中服务语句-唐朝资源网

nmap命令的原理是客户端(nmap)向一个服务器的所有端口发送信息,并看到那些端口的回复信息,回复证明服务器上该端口上的程序是正常的。

唯一的问题是nmap命令需要很长时间来扫描。

如果你的Linux系统没有安装nmap命令,可以执行yum -y install nmap命令安装。

nmap 命令用于扫描本地机器的端口。执行结果如下:

[root@localhost tmp]# nmap -sT 192.168.37.128
Starting Nmap 5.51 ( http://nmap.org ) at 2020-10-19 00:18 CST
Nmap scan report for 192.168.37.128 (192.168.37.128)
Host is up (0.0019s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http          (apache的状态是open)
111/tcp open  rpcbind
Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds

知道nmap命令的用法,我们在脚本中使用的命令是截取http的状态,只要状态为“open”即可

证明apache启动正常,否则证明apache服务启动错误。

开始编写脚本:

#!/bin/bash
# 判断apache服务是否启动,如果没有启动则自动启动
# 使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量stat。
# 只有apache服务的进程名叫`http`
# 截取第二列是获取nmap扫描后的端口状态
stat=$(map -sT 192.168.37.128 | grep tcp | grep ssh | awk '{print $2}')
# 如果变量stat的值是“open”
if [ "$port"=="open" ]
    then
        # 则证明apache服务正常启动,在正常日志中写入一句话即可
        echo "$(date) httpd is ok!" >> /tmp/autostart-acc.log
    else
        # 否则证明apache服务没有启动,自动启动apache服务
        /etc/rc.d/init.d/httpd start &>/dev/null
        # 并在错误日志中记录自动启动apche服务的时间
        echo "$(date) restart httpd!!" >> /tmp/autostart-err.1og
fi

(当然在实际工作中有监控服务器来监控此类问题,以上只是一个练习。)

© 版权声明
THE END
喜欢就支持一下吧
点赞80赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容