看到公司平台有套ISMS系统内,监测脚本用expect实现,仔细研究了下:

需求如下:
#ping一个指定的IP地址,收集丢包率、回包时延;
#设定阀值,如果丢包率、回包时延超过阀值,发出短信或邮件告警。

#!/usr/bin/expect
#ping一个指定的IP地址,收集丢包率、回包时延;
#设定阀值,如果丢包率、回包时延超过阀值,发出短信或邮件告警。
#This script need at least one arguments.
#arguments1: the remote device's IP.

#######用户设置
#设置告警邮件
set Mail_address xxxx@xxxx.com
#设置丢包率阀值
set Packet_loss 20%
#设置回包时延阀值
set Rtt_avg 0.5
#######结束设置

#设置超时时间
set timeout 30
#设置需要PING测试的IP
set IP_test [lindex $argv 0]



#获取PING测试内容
set Ping_info [exec ping $IP_test -c 10 | tail -2]
#获取丢包率信息
set Packet_loss_test [exec echo $Ping_info | head -1 | awk  "{print \$6}"]
#获取回包时延信息
set Rtt_avg_test [exec echo $Ping_info | tail -1 | awk -F/ "{print \$5}"]
#set Rtt_avg_test []
puts "\nIP_test:\n$IP_test\n"
puts "Ping_info:\n$Ping_info\n"
puts "Packet_loss_test:\n$Packet_loss_test\n"
puts "Rtt_avg_test:\n$Rtt_avg_test\n"


后面邮件通知等不会写了,还需要花时间研究,前面也应该加一个判断ping是否在线。。。


expect感觉还是小众,发现51cto中热度很小,问的问题也鲜有回复。自己再研究摸索了一个晚上,修改了代码:

#!/usr/bin/expect -f
#(1)通过ping包检测一组IP地址(每个IP地址带一个描述信息)
#(2)收集对应每个IP地址的丢包率、平均时延(ms),记录数据
#(3)提前预设监控阀值,如果某个IP地址对应丢包率或平均时延高于阀值,发出监控异常的告警
#(4)告警信息以短信(可暂缓)和邮件进行发送,内容包括:IP地址及对应描述信息、丢包率/时延的设定阀值和当前值

#######用户设置
#设置告警通知邮件
set Mail_address xxxx@xxxx.com
#设置丢包率阀值
set Packet_loss 5%
#设置回包时延阀值
set Rtt_avg 100
#设置测试设备IP及对应device描述
set ip(0) 10.10.10.2
set device(0) ***2nj

set ip(1) 10.10.10.6
set device(1) ***2sh

set ip(2) 10.10.10.10
set device(2) ***2bj

set ip(3) 10.10.10.33
set device(3) ***2gr

set ip(4) 10.255.1.2
set device(4) cn2sz

set ip(5) 10.255.1.14
set device(5) cn2bj

set ip(6) 10.255.1.10
set device(6) cn2sh

set ip(7) 10.255.1.6
set device(7) cn2nj

set ip(8) 10.255.1.18
set device(8) cn2gr

#set ip(..) ........
#set device(..) ........
#######结束设置

#循环读取设备IP
for { set index 0 }  { $index < [array size ip] }  { incr index } {
        set IP_test $ip($index)
        set Device_test $device($index)

        #检测设备在线状态
        set IP_status [catch {exec ping $IP_test -c 1} result]
        if { $IP_status == 0 } {
                puts "$Device_test $IP_test is up!\n"
        } else {
                puts "$Device_test $IP_test is down! Please check!\n"
                exec echo "Attention:
        The host $Device_test $IP_test is offline! Please check !

Regards,
from root@ISMS.xxxx.com" | mail -s "Offline Warning" $Mail_address
                continue
        }

        #获取PING测试内容
        set Ping_info [exec ping $IP_test -c 50 | tail -2]
        set Ping_info01 [exec echo $Ping_info | head -1]
        set Ping_info02 [exec echo $Ping_info |  tail -1]
        #获取丢包率信息
        set Packet_loss_test [exec echo $Ping_info | head -1 | awk  "{print \$6}"]
        #获取回包时延信息
        set Rtt_avg_test [exec echo $Ping_info | tail -1 | awk -F/ "{print \$5}"]

        puts "Ping_info:\n$Ping_info\n"
        puts "Packet_loss_test:\n$Packet_loss_test\n"
        puts "Rtt_avg_test:\n$Rtt_avg_test\n"

        #检测丢包率阀值告警并发送邮件通知
        if { $Packet_loss_test >= $Packet_loss } {
                puts "\nPacket_loss Warning!\n"
                exec echo "Attention:
        The Packet_loss is over $Packet_loss! Please check $Device_test $IP_test!

Details: 
        $Device_test        $IP_test
        $Ping_info01
        $Ping_info02
        The given thresholds of Packet_loss is $Packet_loss .
        The given thresholds of Rtt_avg is $Rtt_avg .
        
Regards,
from root@ISMS.xxxx.com" | mail -s "Packet_loss Warning" $Mail_address
        } 

        #检测回包时延阀值告警并发送邮件通知
        if { $Rtt_avg_test >= $Rtt_avg } {
                puts "\nRtt_avg Warning!\n"
                exec echo "Attention:
        The Rtt_avg is over $Rtt_avg ms! Please check $Device_test $IP_test!

Details: 
        $Device_test        $IP_test
        $Ping_info01
        $Ping_info02
        The given thresholds of Packet_loss is $Packet_loss .
        The given thresholds of Rtt_avg is $Rtt_avg .

Regards,
from root@ISMS.xxxx.com" | mail -s "Rtt_avg Warning" $Mail_address
        } 
}


代码感觉好粗鄙,请指点。

代码主要问题在于不会定义expect数组从文件读取数据,所有测试的IP全得手动赋值。