每日一道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
【分析】
-
如果你对脚本中的命令: 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 脚本参考下面的脚本。
?
邮件发送脚本,参考:
[[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)的主要内容,如果未能解决你的问题,请参考以下文章