Python中用Threading/Multiprocess运行airodump-ng无法终止进程求助
解决Python线程中运行Airdump-ng无法终止的问题
嘿,我之前也踩过subprocess+线程管理系统进程的坑,你的问题主要出在输出阻塞、进程组管理和代码结构这几个点上,咱们一步步来解决:
问题根源分析
stdout.read()阻塞主逻辑:Airdump-ng是持续输出的工具,stdout.read()会一直等待进程输出完毕才会往下走,你的代码里sleep5秒后调用这个方法,直接就卡住了,根本没机会执行终止进程的代码。shell=True+os.setsid()的坑:用shell=True时,你启动的其实是一个shell进程,然后shell再启动airodump-ng。这时候Airdump.pid是shell的PID,你杀shell进程,airodump-ng可能会变成孤儿进程继续跑。- 全局变量的不可靠性:嵌套函数里用全局变量传递进程对象,很容易出现变量未正确赋值或者作用域混乱的问题。
修正后的代码方案
import subprocess import threading import os import signal import time def CheckModeMonter(): # 假设这个函数返回你的监控接口,比如"wlan0mon" return "wlan0mon" def run_airodump(interface): # 直接传参数列表,不用shell=True,避免额外的shell进程 return subprocess.Popen( ["airodump-ng", interface], stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid # 让进程成为新会话组的领头进程 ) def read_airdump_output(proc): # 单独开线程处理输出,避免阻塞主逻辑 try: while proc.poll() is None: # 进程还在运行时持续读输出 line = proc.stdout.readline() if not line: break print(line.decode("utf-8").strip()) # 读取剩余的stderr输出 stderr_output = proc.stderr.read().decode("utf-8") if stderr_output: print(f"错误输出: {stderr_output}") except Exception as e: print(f"读取输出时出错: {str(e)}") def RubAirdump(): try: interface = CheckModeMonter() airdump_proc = run_airodump(interface) # 启动输出读取线程,设为守护线程,主程序结束时自动退出 output_thread = threading.Thread(target=read_airdump_output, args=(airdump_proc,)) output_thread.daemon = True output_thread.start() # 让Airdump-ng运行5秒 time.sleep(5) # 终止进程:因为用了os.setsid,要杀掉整个进程组 if airdump_proc.poll() is None: # 检查进程是否还在运行 pgid = os.getpgid(airdump_proc.pid) # 先尝试优雅终止(SIGTERM) os.killpg(pgid, signal.SIGTERM) # 等待2秒看是否终止成功 try: airdump_proc.wait(timeout=2) print("✅ Airdump-ng已优雅终止") except subprocess.TimeoutExpired: # 优雅终止失败,强制杀掉(SIGKILL) os.killpg(pgid, signal.SIGKILL) print("⚠️ 已强制终止Airdump-ng") except Exception as e: print(f"❌ 执行出错: {str(e)}") if __name__ == "__main__": RubAirdump()
关键改进点说明
- 去掉
shell=True:直接传递参数列表更安全,也能确保os.setsid()作用在airodump-ng进程本身,而不是中间的shell进程。 - 分离输出处理线程:把读取输出的逻辑放到单独线程,并且设为守护线程,避免主逻辑被阻塞,同时主程序结束时线程会自动退出。
- 杀掉整个进程组:用
os.killpg()终止整个会话组,确保airodump-ng的所有子进程(如果有的话)都被一起杀掉,不会残留后台进程。 - 优雅终止优先:先尝试
SIGTERM让进程正常退出,失败再用SIGKILL强制终止,尽量避免强制杀进程带来的资源泄漏。
如果之前你尝试的终止方法只杀了单个进程,那肯定没用——因为airodump-ng可能还有子进程,或者你杀的只是shell进程。按上面的代码改,应该就能解决无法终止的问题了。
内容的提问来源于stack exchange,提问作者Kamal Samir
相关产品推荐
相关产品推荐

