macOS下Python批量ping IP脚本运行异常及subprocess报错排查
批量Ping IP脚本问题修复
第一版脚本失效原因
- IP列表定义语法错误:列表内的字符串元素之间漏写逗号,Python会自动将相邻的字符串字面量拼接为一个整体,最终
ip_list仅包含1个无效长IP8.8.8.88.8.4.41.1.1.14.4.4.4,没有按预期存储4个独立IP。 - ping命令参数不兼容:macOS/Linux系统下
ping默认会持续发送数据包不会自动终止,os.popen().read()会一直阻塞等待进程结束,无法走到后续的连通性判断逻辑,这就是观察到没有实际执行有效探测的核心原因。
第一版原代码:
#!/usr/bin/env python3 import os ip_list = ['8.8.8.8' '8.8.4.4' '1.1.1.1' '4.4.4.4'] for ip in ip_list: response = os.popen(f"ping {ip}").read() if "Received = 4" in response: print(f"UP {ip} Ping Successful, Host is UP!") else: print(f"DOWN {ip} Ping Unsuccessful, Host is DOWN.")
第二版重构脚本报错原因
遇到的FileNotFoundError: [Errno 2] No such file or directory: 'ping 8.8.8.8'报错,以及逻辑问题共有三个:
- subprocess传参格式错误:传入列表参数时,每个元素必须对应独立的命令片段,将
ping命令和IP拼接为单个字符串传入时,系统会把整个ping 8.8.8.8当成可执行文件名查找,自然找不到对应程序。 - 冗余调用:
subprocess.run()本身是同步阻塞方法,会等待命令执行完成后再返回,不需要额外调用wait()方法。 - 逻辑与参数错误:一是没有给ping加
-c参数指定发包数量,macOS下会无限发包卡住;二是返回值判断逻辑写反,ping进程返回码为0代表连通,非0代表不通。
第二版原代码及报错:
#!/usr/bin/env python3 import subprocess ip_list = ['8.8.8.8', '8.8.4.4', '1.1.1.1'] for ip in ip_list: p = subprocess.run(['ping '+ip]) p.wait() if p.poll(): print (ip+" is down") else: print (ip+" is up")
matt$ python3 Python_Ping_Public3.py Traceback (most recent call last): File "/Users/matt/Desktop/Python_Ping_Public3.py", line 7, in <module> p = subprocess.run(['ping '+ip]) File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1821, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'ping 8.8.8.8'
macOS环境可直接运行的修正代码
#!/usr/bin/env python3 import subprocess # 列表元素之间必须用逗号分隔 ip_list = ['8.8.8.8', '8.8.4.4', '1.1.1.1', '4.4.4.4'] for ip in ip_list: # macOS ping参数说明:-c 指定发送数据包数量,-W 指定单次探测超时时间(单位:秒) ping_result = subprocess.run( ['ping', '-c', '2', '-W', '2', ip], capture_output=True, text=True ) if ping_result.returncode == 0: print(f"UP {ip} Ping Successful, Host is UP!") else: print(f"DOWN {ip} Ping Unsuccessful, Host is DOWN.")
内容的提问来源于stack exchange,提问作者vr30
相关产品推荐
相关产品推荐

