subprocess.Popen stdout 和 stderr 值不匹配

问题描述

我正在尝试使用 python3 subprocess 模块的 Popen 命令编写脚本。我正在尝试获取以下几个已安装软件的版本。

from subprocess import Popen,PIPE
Nginx_version,err = Popen(["Nginx","-v"],stdout=PIPE,stderr=PIPE).communicate()
print("Nginx Version:" + Nginx_version.decode("utf-8"))
print("Stderr:" + err.decode("utf-8"))
###################OUTPUT####################
Nginx Version:
Stderr: Nginx version: Nginx/1.16.1

有没有办法以标准方式转换和处理 STDOUT 和 STDERR?

解决方法

这种行为看起来很奇怪,文档明确说明

communicate() 返回一个元组(stdout_data、stderr_data)。如果流以文本模式打开,则数据将是字符串;否则,字节。

我会按照以下方式进行设置,注意使用 text=True 以避免解码字节输出。

from subprocess import Popen,PIPE

def get_version(name):
    proc = Popen([name,"--version"],stdout=PIPE,stderr=PIPE,text=True)
    program_version,stderr = proc.communicate()
    exitcode = proc.returncode
    return program_version.strip(),stderr.strip(),exitcode

nginx_version,stderr,exit_code = get_version("nginx")

if exit_code == 0:
    print("Nginx Version: " + nginx_version)
else:
    print("Stderr: " + stderr)

运行上面的代码是否出现同样的不匹配?