【问题标题】:Python getstatusoutput replacement not returning full outputPython getstatusoutput 替换不返回完整输出
【发布时间】:2012-04-29 10:23:26
【问题描述】:

我在 Python 2.* 中发现了这个对 getstatusoutput() 函数的出色替换,它在 Unix 和 Windows 上同样适用。但是,我认为output 的构造方式有问题。它只返回输出的最后一行,但我不知道为什么。任何帮助都会很棒。

def getstatusoutput(cmd):
    """Return (status, output) of executing cmd in a shell."""
    """This new implementation should work on all platforms."""
    import subprocess
    pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
    output = "".join(pipe.stdout.readlines())
    sts = pipe.returncode
    if sts is None: sts = 0
    return sts, output

【问题讨论】:

  • 为什么不在 try 块中使用subprocess.check_call?您可以在except 部分中获取返回码(如果它不为零)。
  • 即使返回码为0,如果我想要输出怎么办?

标签: python pipe stdout


【解决方案1】:

这里有一个错误。

电话:

pipe = subprocess.Popen(...)

开始这个过程。行:

output = "".join(pipe.stdout.readlines())

读取进程的标准输出(如果有错误输出,它可能会被卡住,但由于您没有重定向标准错误,这是安全的;在更一般的情况下,您需要使用.communicate() 函数来避免可能的楔入) .你可能会想:好吧,既然我已经阅读了所有的输出,子进程显然已经完成,所以应该设置pipe.returncode。但实际上,如果你替换:

sts = pipe.returncode
if sts is None: sts = 0

使用包含某种诊断的代码(或完全删除第二行),您会发现,至少在某些系统上,sts None。原因是subprocess 模块还没有机会检索它。您应该将这些行替换为:

sts = pipe.wait()

收集结果并消除对is None 测试的需要。 (即使您使用过.communicate() 和/或已经调用过.wait(),也可以安全地调用.wait()。)

使用"".join(...) 可以稍微更有效地完成:

output = pipe.stdout.read()

话虽如此,它确实为我提供了完整的输出。也许您正在阅读仅使用 '\r' 换行符的内容,并且您的 Python 是在没有通用换行符支持的情况下构建的? (如果我运行产生\r-for-newline 的东西,我仍然会得到所有行,由实际的换行符分隔。)

【讨论】:

  • 感谢您的出色解释。我已经学到了很多东西。但是,我认为您对换行符有所了解。我只从我的职能部门得到'\n'。您能否详细说明换行问题?
  • 根据docs,“通用换行符”意味着:在读取输入流时,输入行以“结尾”任何普通\r\r\n或普通\n将让 Python “看到”只是一个简单的 \n 字符。但这需要在支持的情况下构建 Python。如果没有,一个普通的\r 将被视为\r,如果你print 生成的字符串你可能看不到所有内容。例如:>>> print 'something\relse'出现打印elsething
  • 这是有道理的,但我不应该得到所有的输出与\n 混合?相反,即使我知道子进程(在本例中为 ffmpeg)正在输出更多,我也只是得到一个 '\n'
  • 你应该得到它发送到stdout的所有东西。也许它将其他东西发送到stderr?并且:是的,确实如此:stackoverflow.com/questions/1455532/…
  • 感谢托雷克。重定向 stderr 也不起作用,但是您链接上的帖子之一建议使用 pexpect。它实现起来容易大约十亿倍,输出也很好(嗯,有一些讨厌的转义字符)。非常感谢您的时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多