1. 程式人生 > >每日一道shell練習(04)

每日一道shell練習(04)

shell python 監控 ping

1. 習題

設計一個腳本,監控遠程的一臺主機(假設 ip地址是110.110.110.114)的存活狀態,當發現宕機時發一封郵件給你自己。

提示:

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

2. 習題分析

其實這中需求並不困難,題目也給出了思路。關鍵是確定一個閾值,當檢測到結果符合閾值,就觸發警告,發送警告郵件。

我們可以先在主機上嘗試執行一下 ping -c 命令:

[root@cenvm71 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 腳本參考下面的腳本。

    ?

郵件發送腳本,參考:

[root@cenvm71 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)