学习Linux已经一个月了,不知不觉shell脚本的基本用法已经学习完了,为了检验自己的学习情况,在清明小长假期间花了点时间折腾出了这个脚本。该作品只是练手之作,如果有BUG,请留言指明,我会尽力完善。

    该脚本需要用户给定两个参数,第一个参数是网段的起始ip地址,第二个参数是网段的结束ip地址。起始地址的ip地址最后一段必须是1,如192.168.0.1,结束ip地址的最后一位必须是254,如192.168.10.254。另外,起始和结束ip地址的第一段必须相同。

    注意:

    1、地址范围越大运行程序时间越长。

    2、要ping的对方主机防火墙必须关闭才能探测的到。

    3、本程序的ping超时时间为1秒,发送的包数为1,如果主机之间的线路不稳定或丢包的话,可能判断对方为不在线,可以修改脚本中的ping参数来精确查找。   

    该脚本适用于对没有搭建监控平台的中小型机房巡检,运行该脚本的主机也不要是在线的业务服务器。该脚本也适合向我一样的刚刚shell入门的新手练手,使用的都是比较基本的知识。

    脚本内容如下:

#!/bin/bash
#Program:
#       This program show the online host.
#History:
#2016/4/3    xiaohei   v1.0
#blog:http://zww577593841.blog.51cto.com/6145493/1750689
#环境变量初始化
PATH=./:$PATH
export PATH
LANG=zh_CN.UTF8
#定义变量和数组
#在线主机数
declare -i  uphost=0
#不在线主机数
declare -i  downhost=0
#已经ping的主机个数
declare -i  hostping=0
#ip地址的第一个段
declare  -A ipclass
#信号捕获
trap  'mytrap' INT
#捕捉到终止信号时进行的操作
mytrap(){
        clean_file
        echo "exit"
        exit 1
}
#查找在线主机并将查找到的在线主机保存至当前目录下的uphost.txt文件
hostping(){
        ping -W 2 -c 1 $1 &> /dev/null
        if [ $? -eq 0  ];then
                echo "$1 is up" >> ./uphost.txt
        fi
}
#清理上次运行该脚本生成的uphost.txt文件
clean_file(){
        if [ -f ./uphost.txt ];then
                rm -rf  ./uphost.txt
        fi
}
#显示在线主机
show_uphost(){
        if [ -f ./uphost.txt  ];then
                cat ./uphost.txt | sort -u
                echo "uphost: $(grep -E "[^[:space:]]" ./uphost.txt |  sort -u | wc -l )"               
                sync
        else
                echo "no host is up!"
        fi
}
analyse_ip(){
if [[ $#  -ne 1 ]];then
        echo "need two ip"
        return 1
fi
#判断IP地址合法性
echo "$1" | grep -E "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-3])\.(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.)\
{2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>" &> /dev/null
if [ $?  -ne 0  ] ; then
        echo "The parameter error"
        return 1
fi
if [ "${ipclass[ipend3]}" -ne 254  -o  "${ipclass[ipstart3]}" -ne 1    ];then
        echo "The parameter error"
        return 1
fi
}
#调用函数
clean_file
#获取网络地址第一个字段
ipclass[iphead1]=$(echo "$1" | cut -d. -f1)
ipclass[iphead2]=$(echo "$2" | cut -d. -f1)
[[ ${ipclass[iphead1]} != ${ipclass[iphead2]} ]] && echo "The parameter erro" && exit 1
#获取地址的其他地址段
for((i=1;i<=3;i++));do
        ipclass[ipstart$i]=$(echo "$1" | cut -d. -f$[$i+1])
        ipclass[ipend$i]=$(echo "$2" | cut -d. -f$[$i+1])
done
#调用函数
analyse_ip $1 &&  analyse_ip $2 || exit
#扫描各个网段的在线主机
for((i=${ipclass[ipstart1]};i<=${ipclass[ipend1]};i++));do
        for((j=${ipclass[ipstart2]};j<=${ipclass[ipend2]};j++));do
                for((k=${ipclass[ipstart3]};k<=${ipclass[ipend3]};k++));do
                      #将程序送至后台执行
                      hostping ${ipclass[iphead]}.${i}.${j}.${k} &
                      let hostping++
                done
                #防止一次性执行过多的ping导致主机崩溃,可按照自己的主机进行调整
                if [ $hostping -gt 1000 ];then
                hostping=0
                sleep 1
                fi
        done
done
#调用函数
show_uphost

程序的运行及测试如下:

1)给脚本可执行权限

小黑的日常折腾-网段在线地址扫描shell脚本_shell

2)改变环境变量PATH,运行该脚本,脚本参数格式的要求上文已说明。

小黑的日常折腾-网段在线地址扫描shell脚本_shell_02

3)参数给定错误的提示

小黑的日常折腾-网段在线地址扫描shell脚本_linux_03

4)测试脚本效率,要测试的网段越大,需要的时间越久,我这里最多只测试了2500多台主机的范围。

小黑的日常折腾-网段在线地址扫描shell脚本_linux_04 

    如果您在测试本脚本时发现什么BUG,请留言指出,我会尽力改进,谢谢!