天天看點

python實戰系列之批量主機ping網絡測試(七)

1.需求說明

  工作環境中,經常會有使用到ping對網絡上的主機做網絡測試,如機器上架,下線,測試等一些需要,對于大批量的機器來說,逐個主機ping測試,顯然難以滿足要求,對于機器比較多的場景,可以将需要執行ping測試的IP位址存放至一個檔案内,調用腳本執行網絡測試,友善,便捷。

2.程式内容

vim ping.py 
#!/usr/bin/env python
#_*_ coding:utf8 _*_
#author: Happy
#來自Happy試驗試驗 http://happylab.blog.51cto.com
#腳本主要用于做ping測試

import re
import subprocess

def check_alive(ip,count=1,timeout=1):
        '''
        ping網絡測試,通過調用ping指令,發送一個icmp包,從結果中通過正則比對是否有100%關鍵字,有則表示丢包,無則表示正常
        '''
        cmd = 'ping -c %d -w %d %s' % (count,timeout,ip)

        p = subprocess.Popen(cmd,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                shell=True
        )

        result = p.stdout.read()
        regex = re.findall('100% packet loss',result)
        if len(regex) == 0:
                print "\033[31m%s UP\033[0m" % (ip)
        else:
                print "\033[32m%s DOWN\033[0m" % (ip)


if __name__ == "__main__":

        with file('/root/ip.txt','r') as f:
                for line in f.readlines():
                        ip = line.strip()
                        check_alive(ip)         #執行函數功能調用      

3. 測試結果

python ping.py 
10.16.2.4 DOWN
10.16.2.5 DOWN
10.16.4.16 UP
10.16.4.30 UP
10.16.4.61 UP
10.16.4.65 UP
10.16.4.66 UP
10.16.4.68 UP
10.16.4.74 UP
10.16.4.76 UP
10.16.4.77 UP      

4.關于subprocess子產品學習

   在python中,調用shell中的指令主要有三種方法:1. os.system(), 2.commands子產品,3.subprocess子產品,方法都有所不同。

1.os.system(),調用系統指令,擷取指令輸出結果并接受傳回碼

>>> import os
>>> os.system('df -h')
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2             9.9G  7.3G  2.2G  78% /
tmpfs                 3.9G  4.0K  3.9G   1% /dev/shm
/dev/sda1            1008M   82M  876M   9% /boot
/dev/sda4             899G   36G  818G   5% /data1
10.16.2.8:openstack_glances
                      899G   37G  816G   5% /var/lib/glance/p_w_picpaths
0

>>> result = os.system('df -h')   #儲存傳回值
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2             9.9G  7.3G  2.2G  78% /
tmpfs                 3.9G  4.0K  3.9G   1% /dev/shm
/dev/sda1            1008M   82M  876M   9% /boot
/dev/sda4             899G   36G  818G   5% /data1
10.16.2.8:openstack_glances
                      899G   37G  816G   5% /var/lib/glance/p_w_picpaths
>>> print result
0      

2.cmmands子產品

>>> import commands

#得到指令輸出結果
>>> commands.getoutput('df -h') 
'Filesystem            Size  Used Avail Use% Mounted on\n/dev/sda2             9.9G  7.3G  2.2G  78% /\ntmpfs                 3.9G  4.0K  3.9G   1% /dev/shm\n/dev/sda1            1008M   82M  876M   9% /boot\n/dev/sda4             899G   36G  818G   5% /data1\n10.16.2.8:openstack_glances\n                      899G   37G  816G   5% /var/lib/glance/p_w_picpaths'

#得到指令輸出結果和傳回碼,以元組的形式展示
>>> commands.getstatusoutput('df -h')
(0, 'Filesystem            Size  Used Avail Use% Mounted on\n/dev/sda2             9.9G  7.3G  2.2G  78% /\ntmpfs                 3.9G  4.0K  3.9G   1% /dev/shm\n/dev/sda1            1008M   82M  876M   9% /boot\n/dev/sda4             899G   36G  818G   5% /data1\n10.16.2.8:openstack_glances\n                      899G   37G  816G   5% /var/lib/glance/p_w_picpaths')
>>> 
>>> commands.getstatusoutput('df -h')[0]
0      

3.os.popen()子產品

>>> import os
>>> p = os.popen('df -h')
>>> p.read()
'Filesystem            Size  Used Avail Use% Mounted on\n/dev/sda2             9.9G  7.3G  2.2G  78% /\ntmpfs                 3.9G  4.0K  3.9G   1% /dev/shm\n/dev/sda1            1008M   82M  876M   9% /boot\n/dev/sda4             899G   36G  818G   5% /data1\n10.16.2.8:openstack_glances\n                      899G   37G  816G   5% /var/lib/glance/p_w_picpaths\n'

其他方法,還有p.readline()讀一行,p.readlines()讀取所有的行,和檔案操作的方法相類似!不建議使用這種方法,建議使用subprocess,因為subprocess是os.popen()的更進階封裝,功能更強      

4.subprocess子產品

>>> import subprocess            
>>> p = subprocess.Popen('df -h',stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)

#擷取指令執行結果的傳回碼,通過wait()函數
>>> p.wait()
0

#擷取指令輸出結果(标準輸出),通過read()方法
>>> p.stdout.read()
'Filesystem            Size  Used Avail Use% Mounted on\n/dev/sda2             9.9G  7.3G  2.1G  79% /\ntmpfs                 3.9G  4.0K  3.9G   1% /dev/shm\n/dev/sda1            1008M   82M  876M   9% /boot\n/dev/sda4             899G   36G  818G   5% /data1\n10.16.2.8:openstack_glances\n                      899G   37G  816G   5% /var/lib/glance/p_w_picpaths\n'

#擷取指令錯誤輸出結果,通過read()方法
>>> p.stderr.read()            #為空,說明沒有錯誤輸出,看如下例子
''

#擷取錯誤輸出
>>> subprocess.Popen('ls /etc/password',stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,close_fds=True)
<subprocess.Popen object at 0x7f267528dbd0>
>>> p = subprocess.Popen('ls /etc/password',stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,close_fds=True)
>>> p.stderr.read()
'ls: cannot access /etc/password: No such file or directory\n'

@擷取錯誤輸出的其他方法還有:read(),readline(),readlines(),close(),write()和writelines()等.      

關于subprocess的子產品的用法,可以參考http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html

轉載于:https://blog.51cto.com/happylab/1742282

繼續閱讀