python - ping LAN 的 Python 函数未将结果存储在全局列表中
问题描述
我正在尝试编写一个小脚本以基本上具有诸如 nmap (非常简单的脚本)之类的功能,并且我正在取得进展,但被困在其中的一个愚蠢的部分。
我认为这对我来说是一个很好的学习 python 的时刻。
该脚本成功地 ping 整个子网并打印出有关哪些主机响应的信息。我的下一步是将这些 IP 存储到列表中以供以后处理。这就是我卡住的地方:live_hosts 总是返回空。在函数中打印列表确实会显示当前活动的 IP,但会在每次新调用时被覆盖,然后在 map() 函数完成后完全为空。
import subprocess
import multiprocessing
import ipaddress
# import platform
import socket
#Getting information about network
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP
host = get_ip()
octets = host.split(".")
subnet = ''
for octet in octets:
if octet == octets[-1]:
subnet = subnet[:-1] + "."
break
else:
subnet = subnet + octet + "."
#pinging hosts on network to check for life
ips = (subnet+'%d' % i for i in range(1, 255))
**live_hosts = []**
def ping(ip,live_hosts=live_hosts):
ping = subprocess.call(["ping", "-W", "1", "-c", "1", ip],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
if ping == 0:
print(ip +" is up!")
live_hosts.append(ip)
return live_hosts
with multiprocessing.Pool(200) as p:
p.map(ping,ips)
**print(live_hosts)**
我尝试将 live_hosts 包含为全局变量,创建一个临时列表并将其指向 live_hosts,但没有运气。
我不知道我错过了什么,非常感谢一些建议!谢谢。我知道我也可以更加 Pythonic,所以也欢迎任何 Pythonic 建议!
解决方案
当live_hosts
每个工作人员通过 访问全局列表时p.map(ping,ips)
,它被复制到该工作人员的范围内。当工人第一次出现时,该列表将为空。
然后,worker 中的每个调用都append()
对其自己的副本执行操作,并返回其副本的当前值live_hosts
。
您的调用map()
不会捕获返回值。
做到这一点的正确方法是没有全局live_hosts
列表,没有live_hosts
in ping()
,并且只ping()
返回ip
主机是否可达。
然后用live_hosts = p.map(ping, ips)
.
我认为它会充满很多空值,所以使用列表推导来过滤掉它们:
live_hosts = [x for x in p.map(ping,ips) if x != None]
关于性能,调用ping()
时间最长的是那些只坐在那里等待一秒钟 ( -W 1
) 以 ping 不存在的主机超时的调用。
由于您的目标代码被硬编码为假定 /24(C 类)并尝试 ping 该假定子网中的每个主机,因此您也可以将池大小增加到 254 或将其减少到 127。
map()
除非您有一个填充良好的子网,否则您的整个脚本可能会在操作完成之前等待两次超时。
我会将池大小增加到 254 并将调用更改为 ping 以使用-W 2
或更高,以更好地调查您的网络。
推荐阅读
- algorithm - 是否有一种有效的算法可以打印流网络中的所有边缘不相交路径?
- r - autoplot.survfit 应该适用于多阶段分层吗?
- python - 是否可以在套接字中使用代理链
- python - 在 Python 中使用 pygetwindow 时如何捕获 PyGetWindowException?
- swift - 在 Swift 中获取 Firebase Child 的数量 - If Else 语句
- java - 在范围存储Android 11中检索图像
- android - 如何在没有管理员 SDK 的情况下添加 firebase 自定义声明?
- r - 如何使用操作按钮在 R Shiny 中显示和隐藏表格输出?
- r - 如何在 r 数据框中生成变体标识符和存储桶
- python - 调试时出现 spyder 错误且未提供输入