本文介绍了python subprocess proc.stderr.read() 引入额外的行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想运行一些命令并获取输出到 stderr 的任何内容.我有两个版本的函数可以做到这一点版本 1.

def Getstatusoutput(cmd):"""在shell中执行cmd的返回(状态,输出)"""导入系统mswindows = (sys.platform == "win32")导入操作系统如果不是 mswindows:cmd = '{' + cmd + ';}'pipe = os.popen(cmd + '2>&1', 'r')文本 = pipe.read()sts = pipe.close()如果 sts 为 None:sts = 0if text[-1:] == '\n': text = text[:-1]返回 sts,文本

和版本 2

def Getstatusoutput2(cmd):proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)return_code = proc.wait()返回 return_code、proc.stdout.read()、proc.stderr.read()

第一个版本按照我的预期打印 stderr 输出.第二个版本在每一行之后打印一个空行.我怀疑这是由于版本 1 中的 text[-1:] 行......但我似乎无法在第二个版本中做类似的事情.任何人都可以解释我需要做什么才能使第二个函数生成与第一个函数相同的输出,而没有额外的行(以及最后)?

更新:这是我打印输出的方式这是我的打印方式

 状态、输出、错误 = Getstatusoutput2(cmd)s, oldOutput = Getstatusoutput(cmd)打印oldOutput = <>"%(旧输出)打印错误 = <>"% (错误)
解决方案

您可以使用 subprocess.check_output([cmd], stderr=STDOUT) 来捕获所有输出.

要分别捕获标准输出和标准错误,您可以使用 .communicate():

stdout, stderr = Popen([cmd], stdout=PIPE, stderr=PIPE).communicate()

要获取最后没有换行符的所有行,您可以调用 stderr.splitlines().

为了避免在已经存在的情况下打印额外的换行符,请在打印语句中的变量后添加 ',':

打印行,

或者如果你使用 print() 函数:

print(line, end='')

注意

如果 cmd 产生足够的输出,您的 Getstatusoutput2() 将阻塞,请改用上述解决方案:

>>>len(Getstatusoutput2(['python','-c',"""打印"*"*2**6""""])[1])65>>>len(Getstatusoutput2(['python','-c',"""打印"*"*2**16"""])[1])

Popen.wait() 文档:

等待子进程终止.设置并返回返回码属性.

警告:当使用 stdout=PIPE 和/或 stderr=PIPE 并且子进程生成足够的输出到管道时,这将导致死锁,从而阻止等待操作系统管道缓冲区接受更多数据.使用communication()来避免这种情况.

相关使用communication() 而不是stdin.write()、stdout.read() 或stderr.read()

I want to run some command and grab whatever is output to stderr. I have two versions of function that does this version 1.

def Getstatusoutput(cmd):
    """Return (status, output) of executing cmd in a shell."""

    import sys
    mswindows = (sys.platform == "win32")

    import os
    if not mswindows:
        cmd = '{ ' + cmd + '; }'

    pipe = os.popen(cmd + ' 2>&1', 'r')
    text = pipe.read()
    sts = pipe.close()
    if sts is None: sts = 0
    if text[-1:] == '\n': text = text[:-1]
    return sts, text  

andversion 2

def Getstatusoutput2(cmd):
    proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    return_code = proc.wait()
    return return_code, proc.stdout.read(), proc.stderr.read()

The first version prints stderr output as I expect. The second version prints one blank line after every line. I suspect this is due to text[-1:] line in the version 1...but I can't seem to do something similar in second version. Can anybody explain what I need to do to make second function generate the same output as first one without extra lines in between (and at the very end) ?

Update: Here's how I am printing the outputHere's how I am printing

      status, output, error = Getstatusoutput2(cmd)
      s, oldOutput = Getstatusoutput(cmd)
      print "oldOutput = <<%s>>" % (oldOutput)
      print "error = <<%s>>" % (error)
解决方案

You could use subprocess.check_output([cmd], stderr=STDOUT) to capture all output.

To capture stdout, stderr separately you could use .communicate():

stdout, stderr = Popen([cmd], stdout=PIPE, stderr=PIPE).communicate()

To get all lines without a newline character at the end you could call stderr.splitlines().

To avoid printing additional newline if it is already present add ',' after the variable in a print statement:

print line,

Or if you use print() function:

print(line, end='')

Note

Your Getstatusoutput2() will block if the cmd produces enough output, use above solutions instead:

>>> len(Getstatusoutput2(['python', '-c',"""print "*"*2**6"""])[1])
65
>>> len(Getstatusoutput2(['python', '-c',"""print "*"*2**16"""])[1])

Popen.wait() documentation:

Related Use communicate() rather than stdin.write(), stdout.read() or stderr.read()

这篇关于python subprocess proc.stderr.read() 引入额外的行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 05:59