Python的getstatusoutput更换不返回完整的输出

问题描述:

我在Python 2横跨这个伟大replacment来抓getstatusoutput()功能*,它同样适用于Unix和Windows。不过,我认为output的构建方式有问题。它只返回输出的最后一行,但我不明白为什么。任何帮助都是极好的。Python的getstatusoutput更换不返回完整的输出

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 
+0

为什么不在try块中使用'subprocess.check_call'?你可以在'except'部分得到返回码(如果它不是零)。 – wim 2012-04-18 02:50:54

+0

如果我想要输出,即使返回代码为0,该怎么办? – MFB 2012-04-18 03:00:43

这里有一个错误。

召唤:

pipe = subprocess.Popen(...) 

揭开序幕的过程。行:

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

读取进程的标准输出(如果有错误输出也可能被卡住了,但因为你没有重定向标准错误,这是安全的;在更一般的情况下,你需要使用.communicate()功能以避免可能的楔入)。你可能会想:好,现在我读过所有的输出,子进程显然已经完成了,所以pipe.returncode应设置。但事实上,如果更换:

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

与代码,包括诊断某种(或只是删除第二行完全),你会发现,至少在某些系统上,有时,stsNone。原因是subprocess模块还没有机会检索它。此时应更换这些线路有:

sts = pipe.wait() 

收集结果,并消除对is None测试的需要。 (这是安全地调用.wait()即使你使用.communicate()和/或已经被称为.wait()。)

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

output = pipe.stdout.read() 

所有这一切说,它确实为我获得完整的输出。也许你从对换行只使用'\r'和你的Python没有通用换行的支持是建什么读什么? (如果我运行的东西产生\r -for-newline,我仍然得到所有的行,用实际的换行符分隔。)

+0

感谢这个优秀的解释。我已经学到了很多。不过,我认为你正在使用换行符。我只是从我的功能中得到''n \''。您可以请扩展新行问题吗? – MFB 2012-04-18 04:49:43

+0

每[文档](http://docs.python.org/library/functions.html#open),“通用换行符”是指:读一个输入流时,输入线,任何的普通'“结尾” \ r'或'\ r \ n'或普通的'\ n'会使Python“看见”一个简单的'\ n'字符。但是这需要Python的支持。如果没有,一个普通的'\ r'会被视为'\ r',并且如果你打印出结果字符串,你可能看不到任何东西。例如:>>> print'something \ relse'' * *出现*以打印'elsething'。 – torek 2012-04-18 04:55:26

+0

这很有道理,但不应该让'\ n'混合输入所有输出?相反,即使我知道子进程(在这种情况下是ffmpeg)正在输出更多的信息,我也只是获得一个'\ n'。 – MFB 2012-04-18 05:00:13