每日一道shell练习(04)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一道shell练习(04)相关的知识,希望对你有一定的参考价值。

1. 习题

设计一个脚本,监控远程的一台主机(假设 ip地址是110.110.110.114)的存活状态,当发现宕机时发一封邮件给你自己。

提示:

  • 你可以使用 ping 命令 :
ping   -c  10 110.110.110.114
  • 脚本可以搞成死循环。

2. 习题分析

其实这中需求并不困难,题目也给出了思路。关键是确定一个阈值,当检测到结果符合阈值,就触发警告,发送警告邮件。

我们可以先在主机上尝试执行一下 ping -c 命令:

[[email protected] work]# ping -c 10 192.168.188.203 
PING 192.168.188.203 (192.168.188.203) 56(84) bytes of data.
64 bytes from 192.168.188.203: icmp_seq=1 ttl=128 time=1.53 ms
64 bytes from 192.168.188.203: icmp_seq=2 ttl=128 time=0.469 ms
64 bytes from 192.168.188.203: icmp_seq=3 ttl=128 time=0.632 ms
64 bytes from 192.168.188.203: icmp_seq=4 ttl=128 time=0.562 ms
64 bytes from 192.168.188.203: icmp_seq=5 ttl=128 time=0.785 ms
64 bytes from 192.168.188.203: icmp_seq=6 ttl=128 time=0.591 ms
64 bytes from 192.168.188.203: icmp_seq=7 ttl=128 time=0.569 ms
64 bytes from 192.168.188.203: icmp_seq=8 ttl=128 time=0.604 ms
64 bytes from 192.168.188.203: icmp_seq=9 ttl=128 time=1.19 ms
64 bytes from 192.168.188.203: icmp_seq=10 ttl=128 time=0.643 ms

--- 192.168.188.203 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9010ms
rtt min/avg/max/mdev = 0.469/0.758/1.533/0.321 ms

从输出结果来看,检测主机存活状态就是检测主机能不能ping通。ping命令返回的结果报告中,最重要的就是那个丢包率。当主机宕机断线时,丢包率就会是100%,如果主机正常在线,丢包率就会是0%。实际上,当丢包率大于20%时,网络连接状态就已经出现问题了。

根据以上分析,就可以定下触发警告的阈值是20%。当丢包率大于20%,就可以发邮件了。

接下来,只要能获取到丢包率就可以了。用什么方法呢?看下面的答案脚本。

3. 具体脚本

#!/bin/bash
IP="110.110.110.114"
to_mail="[email protected]"  # 你自己用来接收警告信息的邮箱地址

while true  : 
do
result=`ping -c 10 $IP | grep "received" | awk -F‘received, |%‘ ‘{print $2}‘`

if [ -z $result ];then
  echo "script sth wrong."
  exit
elif [ $result -ge 20 ];then

  # 这个python 脚本是用来实现发送邮件功能的,请参考
  python /usr/local/sbin/work/mail.py $to_mail "host down"  "$IP is down"
fi

sleep 30

done

【分析】

  1. 如果你对脚本中的命令: ping -c 10 $IP | grep "received" | awk -F‘received, |%‘ ‘{print $2}‘ ,运行不是很了解,那么你可以按照管道从左至右执行一遍。

  2. 这里有一个awk 的技巧,awk -F选项接分隔符,这个选项的用法非常灵活。例如:-F‘#|:’,表示分隔符既可以是“#”也可以是“:”。

    所以,回到我们的习题中,-F‘received, |%‘,就表示分隔符是“received, ”注意received最后是有一个空格,同时,分隔符也可以是“%”。

  3. 变量 result 存储丢包率。if 条件里,首先判断一下变量是否为空,如果为空则脚本有问题。

    如果变量result 没有问题,且丢包率大于20,则调用 python 脚本发邮件。

    python 脚本参考下面的脚本。

    ?

邮件发送脚本,参考:

[[email protected] work]# cat mail.py 
#!/usr/bin/env python
#-*- coding: UTF-8 -*-
import os,sys
reload(sys)
sys.setdefaultencoding(‘utf8‘)
import getopt
import smtplib
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from  subprocess import *
def sendqqmail(username,password,mailfrom,mailto,subject,content):
    gserver = ‘smtp.163.com‘
    gport = 25
    try:
        msg = MIMEText(unicode(content).encode(‘utf-8‘))
        msg[‘from‘] = mailfrom
        msg[‘to‘] = mailto
        msg[‘Reply-To‘] = mailfrom
        msg[‘Subject‘] = subject
        smtp = smtplib.SMTP(gserver, gport)
        smtp.set_debuglevel(0)
        smtp.ehlo()
        smtp.login(username,password)
        smtp.sendmail(mailfrom, mailto, msg.as_string())
        smtp.close()
    except Exception,err:
        print "Send mail failed. Error: %s" % err
def main():
    to=sys.argv[1]
    subject=sys.argv[2]
    content=sys.argv[3]
##定义发送警告信息的邮箱的账号和密码,
##你需要修改成你自己的账号和密码(请不要
##把真实的用户名和密码放到网上公开,否则你会死的很惨),
##我测试用的是163网易的邮箱
    sendqqmail(‘[email protected]‘,‘888888‘,‘[email protected]‘,to,subject,content)
if __name__ == "__main__":
    main()

#####脚本使用说明######
#1. 首先定义好脚本中的邮箱账号和密码
#2. 脚本执行命令为:python mail.py 目标邮箱 "邮件主题" "邮件内容"

【分析】

发送邮件的脚本,使用了python,需要读者自己去扩展学习了解一下。

4. 练习结果

因为 110.110.110.114 是我假设出来的一个ip,所以,肯定ping 不同。

将 shell 脚本后台运行后,就可以在我的 qq 邮箱[email protected] 里收到host 主机宕机的信息了。

技术分享图片

5. 结语

今天的练习题需要检测主机状态,然后发邮件通知。功能其实很简单,但是对于新手来说,python 脚本可能是一个难点。写脚本很少有写一次就能100%成功的,所以需要大家多写多练,多调试。

以上是关于每日一道shell练习(04)的主要内容,如果未能解决你的问题,请参考以下文章

每日一道shell脚本练习(02)

每日一道shell练习(03)

每日一道shell练习(10)——统计字符数

每日一道shell练习(06)——检测端口服务

每日一道shell练习(09)——sed处理

老男孩教育每日一题-第60天-一道实用Linux运维问题的9种Shell解答方法!