使用subprocess.Popen执行脚本遇OSError: [WinError 6]句柄无效问题求助
解决subprocess.Popen的WinError 6错误
问题描述
我尝试运行一个以脚本路径为参数的函数,但遇到了OSError: [WinError 6] The handle is invalid错误。已尝试添加stdin=subprocess.DEVNULL的解决方案,但仍然无效。
原函数代码
import subprocess def run_python_script(path: str): return_value = subprocess.Popen(args=[path,], stdin=subprocess.DEVNULL) time.sleep(3) if return_value.returncode is None: return 1, "Script run correctly" else: return 0, f"Error occured while running script - [Errno {return_value.returncode}]"
完整错误信息
[2022-08-23 13:56:27] Exception ignored in: <function Popen.__del__ at 0x000001E32DA28B80> Traceback (most recent call last): File "C:\Python\Python310\lib\subprocess.py", line 1070, in __del__ self._internal_poll(_deadstate=_maxsize) File "C:\Python\Python310\lib\subprocess.py", line 1472, in _internal_poll if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0: OSError: [WinError 6] The handle is invalid Exception ignored in: <function Handle.Close at 0x000001E32D7FBD90> Traceback (most recent call last): File "C:\Python\Python310\lib\subprocess.py", line 199, in Close CloseHandle(self) OSError: [WinError 6] The handle is invalid
问题原因
这个错误源于子进程句柄在Python垃圾回收时被重复关闭或引用失效。当Popen对象被销毁时,其__del__方法尝试轮询进程状态,但此时句柄已无效。
解决办法
修改后的代码
import subprocess import time def run_python_script(path: str): # 重定向所有标准流,避免句柄泄漏 with subprocess.Popen( args=[path], stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False ) as proc: try: # 等待3秒或进程结束,取先发生的 stdout, stderr = proc.communicate(timeout=3) if proc.returncode == 0: return 1, "脚本运行正常" else: err_msg = stderr.decode('utf-8', errors='ignore').strip() return 0, f"脚本运行出错 - [错误码 {proc.returncode}],错误信息:{err_msg}" except subprocess.TimeoutExpired: # 超时说明进程仍在运行,清理资源后返回正常状态 proc.kill() proc.communicate() return 1, "脚本运行正常(超时仍在运行)"
关键改进点
- 用
with语句管理Popen对象,自动释放资源,避免句柄泄漏。 - 重定向
stdout和stderr,彻底解决流句柄的无效引用问题。 - 用
communicate(timeout=3)替代time.sleep(3),更可靠地等待进程状态,同时避免进程输出阻塞。 - 捕获超时异常,处理进程仍在运行的场景,并清理子进程资源。
内容的提问来源于stack exchange,提问作者Karol
相关产品推荐
相关产品推荐

