cdchenli 发表于 2018-8-19 06:15:53

每日一道shell练习(04)

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


[*]你可以使用 ping 命令 :
  

ping   -c10 110.110.110.114  


[*]脚本可以搞成死循环。
2. 习题分析
  其实这中需求并不困难,题目也给出了思路。关键是确定一个阈值,当检测到结果符合阈值,就触发警告,发送警告邮件。
  我们可以先在主机上尝试执行一下 ping -c 命令:
  

# 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="123456@qq.com"# 你自己用来接收警告信息的邮箱地址
  

  
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
  

  

  【分析】


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

[*]  这里有一个awk 的技巧,awk-F选项接分隔符,这个选项的用法非常灵活。例如:-F‘#|:’,表示分隔符既可以是“#”也可以是“:”。
  所以,回到我们的习题中,-F'received, |%',就表示分隔符是“received, ”注意received最后是有一个空格,同时,分隔符也可以是“%”。

[*]  变量 result 存储丢包率。if 条件里,首先判断一下变量是否为空,如果为空则脚本有问题。
  如果变量result 没有问题,且丢包率大于20,则调用 python 脚本发邮件。
  python 脚本参考下面的脚本。
  ​

  邮件发送脚本,参考:
  

# 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
  
fromsubprocess 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
  subject=sys.argv
  content=sys.argv
  
##定义发送警告信息的邮箱的账号和密码,
  
##你需要修改成你自己的账号和密码(请不要
  
##把真实的用户名和密码放到网上公开,否则你会死的很惨),
  
##我测试用的是163网易的邮箱
  sendqqmail('abc@163.com','888888','abc@163.com',to,subject,content)
  
if __name__ == "__main__":
  main()
  

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

  

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

4. 练习结果
  因为 110.110.110.114 是我假设出来的一个ip,所以,肯定ping 不同。
  将 shell 脚本后台运行后,就可以在我的 qq 邮箱123456@qq.com 里收到host 主机宕机的信息了。


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


页: [1]
查看完整版本: 每日一道shell练习(04)