工做中會遇到判斷服務器是否存活的場景,好比:批量重啓服務器後,各宿主機或虛擬機是否啓動成功。python
檢測服務器是否存活的原理很簡單:先檢查服務器是否通(ping);若是不通則檢查服務器上的服務是否通,若是服務也不通,則說明這臺服務器沒有開啓。可使用的工具備:ping、telnet、nmap或者tcping等。linux
nmap功能強大,用處普遍;tcping能夠在服務器禁ping的狀況下檢查機器是否存活(好比windows機器默認就是禁ping的)。在這裏,我用的是ping和telnet組合。windows
關於ping工具,合理的使用相關參數比較有利於排查問題,好比:"-c"參數能夠用來限制發送ping多少個包,"-i"參數能夠用來限制ping的頻率等。舉例:bash
ping -c2 -i0.02 www.baidu.com > /dev/null 2>&1
上一段代碼意思爲:以0.02秒的間隔時間ping www.baidu.com 2次,並將結果(正確或錯誤)引入到「黑洞」(丟棄),合理的使用參數能夠幫助咱們快速判斷目標主機是否可達。固然,會有人問:你將測試結果引入到黑洞,我怎麼知道目標主機是通仍是不通呢?這個時候能夠經過判斷操做狀態得知,命令爲:服務器
echo $?
若是上面的結果返回值爲0,說明www.baidu.com可達,不然www.baidu.com可能不通,須要進行下一步再判斷。有人說,經過手動執行命令麻煩,能否再精巧些?那就寫成腳本吧,以下:tcp
#!/bin/bash # test. ping -c2 -i0.02 www.baidu.com > /dev/null 2>&1 if [ $? -eq 0 ];then echo "Host can access ...." else ... fi
解釋上面那段腳本,若是主機不通,則執行後續動做,這些後續動做放在"else"代碼塊中,後續動做可使用nmap、telnet等工具,這裏介紹telnet。工具
有人會說,telnet容易,若是telnet程序一直卡在那裏則說明服務器端口不通,而後經過「CTRL+c」終止就好了,可是怎樣在腳本中使用telnet呢?簡單,經過Linux的管道功能(「|」),可讓腳本沉睡一段時間,這段時間內telnet執行任務,待沉睡時間到期則終止telnet程序。話雖如此,怎樣實現呢?以下:測試
(sleep 1;) | telnet www.baidu.com 80
判斷某臺服務器是否存活,能夠先ping IP,再telnet port,若是是測試一個IP,則可將腳本寫成以下:code
#!/bin/bash # test. host= www.baidu.com port=80 telnet_file=/tmp/telnet_file.txt ping -c2 -i0.02 $host > /dev/null 2>&1 if [ $? -eq 0 ];then echo "$host can access ...." else (sleep 1;) | telnet $host $port > $telnet_file grep -B 1 \] $telnet_file > /dev/null 2>&1 if [ $? -eq 0 ];then echo "$host can access ..." else echo "$host can not access !!!"
fi fi
上面的腳本是針對一個IP進行判斷,說實話若是是判斷一臺服務器是否可達的話直接終端敲命令就知道了,不須要「大費周折」寫腳本了,可是若是同時測試多臺機器就須要用到腳本了。對於編寫批量判斷多臺主機是否可達的腳本,只須要將上述思路稍做整理,靈活使用linux基礎命令便可實現。固然,若是目標機器很是多的狀況下,推薦使用ansible或者saltstack,或者乾脆寫個python多進程的腳本去判斷。server
下面貼出我以前基於ping和telnet工具寫的腳本,大體原理和上面講述的類似,在執行腳本前,請先編輯服務器配置文件。
執行腳本:
renxiaowei$ cat check.sh #!/bin/bash # 功能:一鍵檢測宿主機、虛擬機是否存活 # 做者:任小爲 # 版本:v1.0 file=server.txt result_base=/tmp/check_host_net rm -rf $result_base mkdir -p $result_base super_host(){ super_ip_list=${result_base}/super_ip_list.txt super_alive=${result_base}/super_alive.txt super_die=${result_base}/super_die.txt super_telnet=${result_base}/super_telnet.txt echo "" echo -e "\033[44;36m檢測宿主機是否存活... \033[0m" egrep -v "#|^$" $file | awk '{print $1,$2}' | uniq > $super_ip_list count=0 for ip in $(cat ${super_ip_list} | awk '{print $1}');do let count++ echo "count=$count" ping -c 2 -i 0.02 $ip > /dev/null 2>&1 if [ $? -eq 0 ];then echo $ip >> ${super_alive} else super_port=`grep $ip ${super_ip_list} | awk '{print $2}'` (sleep 1;) | telnet $ip ${super_port} >> ${super_telnet} fi done if [ -e ${super_telnet} ];then super_ip=${result_base}/super_ip.txt cat ${super_ip_list} | awk '{print $1}' > ${super_ip} cat ${super_telnet} | grep -B 1 \] | grep [0-9] | awk '{print $3}' | cut -d '.' -f 1,2,3,4 >> ${super_alive} cat ${super_ip} ${super_alive} | sort | uniq -u > ${super_die} fi echo "" echo -e "\033[32;49;1m存活的宿主機: \033[31;49;0m" echo -e "`cat ${super_alive}`\n" if [ -s ${super_die} ];then echo -e "\033[31;49;1m檢測不通的宿主機:\033[31;49;0m" echo -e "\033[31;49;1m`cat ${super_die}`\033[31;49;0m\n" else echo -e "\033[44;36m全部宿主機都存活.\033[0m\n" fi } sub_host(){ sub_ip_list=${result_base}/sub_ip_list.txt sub_alive=${result_base}/sub_alive.txt sub_die=${result_base}/sub_die.txt sub_telnet=${result_base}/sub_telnet.txt echo "" echo -e "\033[44;36m檢測虛擬機是否存活... \033[0m" egrep -v "#|^$" $file | awk '{print $3,$4}' | uniq > $sub_ip_list sub_count=0 for sub_ip in $(cat ${sub_ip_list} | awk '{print $1}');do let sub_count++ echo "count=${sub_count}" ping -c 2 -i 0.02 ${sub_ip} > /dev/null 2>&1 if [ $? -eq 0 ];then echo ${sub_ip} >> ${sub_alive} else sub_port=`grep ${sub_ip} ${sub_ip_list} | awk '{print $2}'` (sleep 1;) | telnet ${sub_ip} ${sub_port} >> ${sub_telnet} fi done if [ -e ${sub_telnet} ];then sub_ip=${result_base}/sub_ip.txt cat ${sub_ip_list} |awk '{print $1}' > ${sub_ip} cat ${sub_telnet} | grep -B 1 \] | grep [0-9] | awk '{print $3}' | cut -d '.' -f 1,2,3,4 >> ${sub_alive} cat ${sub_ip} ${sub_alive} | sort | uniq -u > ${sub_die} fi echo "" echo -e "\033[32;49;1m存活的虛擬機: \033[31;49;0m" echo -e "`cat ${sub_alive}`\n" if [ -s ${sub_die} ];then echo -e "\033[31;49;1m檢測不通的虛擬機:\033[31;49;0m" echo -e "\033[31;49;1m`cat ${sub_die}`\033[31;49;0m\n" else echo -e "\033[44;36m全部虛擬機都存活.\033[0m\n" fi } case $1 in super) super_host ;; vm) sub_host ;; help) echo "" echo "`grep "功能" $file`" echo "super選項表明檢測宿主機;" echo -e "vm選項表明檢測虛擬機.\n" ;; *) echo "" echo -e $"Usage: sh $0 { super | vm | help }\n" esac exit 0
服務器配置文件格式:
renxiaowei$ cat server.txt #功能:用於一鍵檢測宿主機、虛擬機是否存活的文件 #格式:vm宿主機 ------ 宿主機管理端口 ---- 虛擬機 ---- 虛擬機管理端口 192.168.2.2 80 192.168.2.50 22 192.168.2.3 80 192.168.2.51 22 192.168.3.2 80 192.168.3.52 22
請將腳本、服務器配置文件放在同一個目錄下。
腳本執行方式:chmod + x check.sh && ./check.sh [super|vm|help] 或者 sh check.sh [super|vm|help] 。
腳本參數「super」意爲宿主機檢測;參數「vm」意爲虛擬機檢測。