subprocess.Popen stdout解码报错:UnicodeDecodeError无法解析0x84字节
解决UnicodeDecodeError:cmd.exe输出的utf-8解码失败问题
这个坑我踩过!你遇到的问题核心很明确:Windows下cmd.exe的输出编码根本不是UTF-8,哪怕sys.stdout.encoding显示的是utf-8也没用——那是你当前Python进程的标准输出编码,和cmd子进程的输出编码完全是两码事。
问题根源拆解
你看到的字节0x84,在Windows的OEM编码(比如西欧常用的cp850)里正好对应字符ä,但UTF-8编码中0x84是无效的起始字节,所以用utf-8解码必然报错。cmd默认会用系统的OEM代码页输出内容,而不是UTF-8。
三种解决方案
1. 直接指定正确的编码解码
如果你确定目标系统的cmd用的是cp850(西欧系统常见),直接把解码代码改成:
line.decode('cp850')
如果是中文系统,cmd默认编码是cp936,对应改编码名即可。
2. 动态获取cmd的当前编码(通用方案)
为了让代码适配不同系统的cmd编码,可以先调用chcp命令获取当前代码页,再用对应编码解码:
import subprocess def get_cmd_code_page(): # 调用chcp获取当前代码页,输出类似b'Active code page: 850\n' chcp_output = subprocess.check_output(["chcp"], shell=False, text=False) # 解析出数字代码页,转成Python能识别的编码名(比如cp850) code_page_num = chcp_output.decode('ascii').split(':')[-1].strip() return f"cp{code_page_num}" # 获取编码后再解码cmd输出 cmd_encoding = get_cmd_code_page() prc = subprocess.Popen(["cmd.exe"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) for line in prc.stdout: decoded_line = line.decode(cmd_encoding) # 后续处理逻辑 print(decoded_line)
3. 强制cmd用UTF-8输出(推荐现代系统使用)
可以在调用cmd时先执行chcp 65001(65001是UTF-8对应的Windows代码页),强制cmd用UTF-8输出内容,这样就能直接用utf-8解码了:
import subprocess # 先切换编码为UTF-8,再执行你的命令 prc = subprocess.Popen( ["cmd.exe", "/c", "chcp 65001 && your_command_here"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, stderr = prc.communicate() # 直接用utf-8解码 decoded_stdout = stdout.decode('utf-8') print(decoded_stdout)
注意:部分旧版Windows(比如Win7)的cmd在使用65001编码时可能存在小问题,但Win10及以后的系统完全没问题。
额外提醒
sys.stdout.encoding反映的是Python进程自身的标准输出编码,和子进程cmd的输出环境无关——子进程的编码由它自己的运行终端(cmd)的代码页决定,两者是独立的,别搞混了哦。
内容的提问来源于stack exchange,提问作者Harper
相关产品推荐
相关产品推荐

