使用subprocess.Popen管道链时输出utf-8解码报错如何解决
错误根因
subprocess.Popen 实例的 stdout 属性是 _io.BufferedReader 字节流对象,并非 subprocess.run 返回的字节串(bytes)类型,decode 是 bytes 类型的专属方法,因此直接调用会抛出属性不存在的错误。
方案1:使用
communicate() 读取输出(最推荐,避免管道死锁) Popen.communicate() 会等待命令执行完成,返回元组 (标准输出字节串, 标准错误字节串),拿到字节串后即可正常调用 decode 方法:
import subprocess r1 = subprocess.Popen(['command1'], stdout=subprocess.PIPE) r2 = subprocess.Popen(['command2'], stdin=r1.stdout, stdout=subprocess.PIPE) # 关闭上游进程的stdout,避免下游进程收不到SIGPIPE信号 r1.stdout.close() r3 = subprocess.Popen(['command3'], stdin=r2.stdout, stdout=subprocess.PIPE) r2.stdout.close() # 读取最终进程输出 stdout_data, stderr_data = r3.communicate() # 解码为utf-8字符串 result = stdout_data.decode('utf-8')
方案2:直接读取流对象内容
如果不需要处理标准错误,也可以直接调用 BufferedReader 的 read() 方法读取全部字节内容后解码:
import subprocess r1 = subprocess.Popen(['command1'], stdout=subprocess.PIPE) r2 = subprocess.Popen(['command2'], stdin=r1.stdout, stdout=subprocess.PIPE) r3 = subprocess.Popen(['command3'], stdin=r2.stdout, stdout=subprocess.PIPE) # 读取全部字节后解码 result = r3.stdout.read().decode('utf-8') # 执行完成后等待进程退出回收系统资源 r3.wait() r2.wait() r1.wait()
方案3:直接指定编码参数(Python 3.7+ 支持)
初始化 Popen 时指定 encoding='utf-8',输出会自动解码为字符串,不需要手动调用 decode:
import subprocess r1 = subprocess.Popen(['command1'], stdout=subprocess.PIPE, encoding='utf-8') r2 = subprocess.Popen(['command2'], stdin=r1.stdout, stdout=subprocess.PIPE, encoding='utf-8') r3 = subprocess.Popen(['command3'], stdin=r2.stdout, stdout=subprocess.PIPE, encoding='utf-8') result = r3.stdout.read()
内容的提问来源于stack exchange,提问作者jozinko9
相关产品推荐
相关产品推荐

