-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
justping.py
155 lines (127 loc) · 4.27 KB
/
justping.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""通过 ping 命令找出响应时间最短的 ip 或域名
支持 windows,unix,linux
"""
import re
import os
import subprocess
import sys
def ping(host):
"""返回 ping 结果
host 参数应为字符串类型的 ip 或域名
'192.168.1.1' or 'www.baidu.com'
返回 host, ip, time, lost
host:域名或 ip,字符串类型
ip:ip 地址,字符串类型,默认值为'0.0.0.0'
time:平均响应时间(ms),int 类型,默认值为0
lost:平均丢包率(%),int 类型,默认值为0
返回值示例:
('baidu.com', '123.125.114.144', 70, 0)
"""
os_name = os.name
# 根据系统平台设置 ping 命令
if os_name == 'nt': # windows
cmd = 'ping ' + host
else: # unix/linux
cmd = 'ping -c 4 ' + host
# 执行 ping 命令
sub = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
out = sub.communicate()[0]
if not out:
return host, '0.0.0.0', 0, 100
# 替换换行符,因为在正则表达式中
# 'a$' 匹配 'a\r\n' 中的 'a\r'
text = out.replace('\r\n', '\n').replace('\r', '\n')
# 使用正则匹配 ip 地址: [192.168.1.1] (192.168.1.1)
ip = re.findall(r'(?<=\(|\[)\d+\.\d+\.\d+\.\d+(?=\)|\])', text)
# 获取时间信息
if os_name == 'nt':
time = re.findall(r'\d+(?=ms$)', text)
else:
time = re.findall(r'(?<=\d/)[\d\.]+(?=/)', text)
# 丢包率
lost = re.findall(r'\d+(?=%)', text)
ip = ip[0] if ip else '0.0.0.0'
# 小数点四舍五入
time = int(round(float(time[0]))) if time else 0
lost = int(round(float(lost[0]))) if lost else 0
return host, ip, time, lost
def get_hosts(filename):
"""从文件中读取 ip/域名
返回 ip/域名 列表,默认值为空
"""
hosts = []
with open(filename) as f:
for line in f:
line = line.strip().strip('.,/')
if line:
hosts.append(line)
return hosts
if __name__ == '__main__':
# 处理命令行参数
argvs = sys.argv
leng = len(argvs)
hosts = []
filename = 'hosts.txt'
add = False
ips = []
# 如果包含命令参数
if leng >= 2:
name = argvs[1]
# 第一个参数是个文件
if os.path.isfile(name):
filename = name
if leng > 2:
# 第二个参数是 +
if argvs[2] == '+':
add = True
ips = argvs[3:]
else:
ips = argvs[2:]
else:
if name == '+':
add = True
ips = argvs[2:]
else:
ips = argvs[1:]
# 处理 ip/域名参数
if ips:
for s in ips:
name = s.strip('.,/')
name = re.sub(r'https?://', '', name)
hosts.append(name)
# 既没有 ip/域名参数,也没有文件参数同时默认文件也不存在
if not hosts and not os.path.isfile(filename):
sys.exit('No ip/host or the file("%s") not existed!' % (filename))
if not hosts: # 如果没有参数,使用默认文件
# 移除重复项
hosts = list(set(get_hosts(filename)))
else:
hosts = list(set(hosts))
# 如果包含 + 参数,合并 ip/域名信息
if add:
hosts = list(set(get_hosts(filename) + hosts))
if not hosts: # 如果最终都没获取到 ip/域名 信息
sys.exit('Not find ip/host')
result_time = {}
print '#' * 55
# 固定字符串长度
print 'host(ip)'.rjust(33), 'time'.rjust(8), 'lost'.rjust(8)
for x in hosts:
host, ip, time, lost = ping(x)
result_time.update({host: time})
if time == 0:
lost = 100
print ('%s(%s): ' % (host, ip)).rjust(35),\
('% 3sms' % (time)).rjust(6),\
('% 2s%%' % (lost)).rjust(8)
times = sorted(result_time.itervalues())
# 去除 time 为0的
times = [i for i in times[:] if i]
print '#' * 55
if times:
for k, v in result_time.iteritems():
if v == times[0]:
print '%s has min ping time: %s ms' % (k, v)