【问题标题】:Why does reading from "git --version" show up on a different channel from "python --version" via subprocess?为什么通过子进程从“git --version”读取显示在与“python --version”不同的通道上?
【发布时间】:2019-07-25 19:44:51
【问题描述】:

谁能解释一下为什么以下命令(“python --version”)的输出会变成标准错误而不是标准输出?

import shlex, subprocess

cmd = subprocess.Popen(shlex.split("git --version"), stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)

std_out, std_err = cmd.communicate()

print("std_out: {}".format(std_out))
print("std_err: {}".format(std_err))

cmd = subprocess.Popen(shlex.split("python --version"), stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)

std_out, std_err = cmd.communicate()

print("std_out: {}".format(std_out))
print("std_err: {}".format(std_err))

这是打印出来的:

std_out: git version 2.19.2

std_err: 
std_out: 
std_err: Python 2.7.15

我是 python 新手,不知道为什么它在上述情况下表现不同。谢谢你。

【问题讨论】:

  • 我认为gitpython 对这些命令使用不同的输出通道。看起来git 使用stdoutpython 使用stderr。你这边没有错。另见superuser.com/questions/453598/…
  • 谢谢。在这种情况下,无论程序可能使用哪个通道(stdout 或 stderr),我都必须添加更多代码来读取预期数据。
  • 这与subprocess无关。完全由程序决定是写入 stdout 还是 stderr。
  • 顺便说一句,与自己进行拆分并将['python', '--version'] 放在代码中相比,以这种方式使用shlex.split() 是一种坏习惯。当然,当您的值完全恒定时,它们是等价的,但最终您会执行类似shlex.split('foo --arg %s' % (someStr,)) 的操作,并且当参数包含空格或其他旨在为文字的语法时,它会中断;而['foo', '--arg', someStr] 是明确的,无论someStr 包含什么,它的工作方式都是一样的。
  • 顺便说一句,我认为对 POSIX 标准的字面解读将使 --version 结果转到标准输出,因为当调用 program --version 时,该版本是用户要求的确切输出, vs 信息或诊断日志。但是,我完全理解为什么人们会这样做——如果你已经有一个将版本和使用信息写入 stderr 的函数(对于使用 incorrect 用法调用程序的情况,或者当它是除了向 stderr 提供信息性消息之外,还向 stdout 写入实际输出),在这两种情况下都可以很容易地调用相同的东西。

标签: python python-2.7 subprocess


【解决方案1】:

您的代码没有问题。不同的结果仅仅是因为这两个程序为(至少)这些命令使用了不同的输出通道。特别是,看起来git 使用的是stdout,而python 使用的是stderr

为了交叉检查一个程序使用哪个频道,您可以使用this answer中指示的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2021-01-07
    • 2016-04-09
    相关资源
    最近更新 更多