python subprocess proc.stderr.read() 引入多余行?
我想运行一些命令,并获取输出到错误信息(stderr)中的内容。我有两个版本的函数来实现这个功能。
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
还有第二个版本。
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()
第一个版本的输出正如我所期待的那样,能正确打印错误信息。而第二个版本在每一行后面多打印了一行空白。我怀疑这是因为第一个版本中的 text[-1:] 这一行……但我在第二个版本中似乎无法做到类似的处理。有没有人能告诉我,我需要做些什么才能让第二个函数的输出和第一个一样,没有多余的空行(包括最后一行)?
更新:这是我打印输出的方式。
status, output, error = Getstatusoutput2(cmd)
s, oldOutput = Getstatusoutput(cmd)
print "oldOutput = <<%s>>" % (oldOutput)
print "error = <<%s>>" % (error)
2 个回答
你可以使用 .strip()
方法:
def Getstatusoutput2(cmd):
proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
return_code = proc.wait()
return return_code, proc.stdout.read().strip(), proc.stderr.read().strip()
string.strip(s[, chars])
这个方法会返回一个新的字符串,去掉了开头和结尾的字符。如果你不提供
chars
或者给它传None
,那么它会去掉空白字符。若你提供了chars
,并且它不是None
,那么chars
必须是一个字符串;这个字符串中的字符会被从调用这个方法的字符串的两端去掉。
string.whitespace
这是一个包含所有被认为是空白字符的字符串。在大多数系统中,这包括 空格、制表符、换行符、回车符、分页符 和 垂直制表符。
你可以使用 subprocess.check_output([cmd], stderr=STDOUT)
来捕获所有输出。
如果你想分别捕获标准输出和错误输出,可以使用 .communicate()
:
stdout, stderr = Popen([cmd], stdout=PIPE, stderr=PIPE).communicate()
如果你想获取所有行而不在最后加换行符,可以调用 stderr.splitlines()
。
为了避免在打印时多出一个换行符,如果变量后面已经有换行符,可以在打印语句中加上 ','
:
print line,
或者如果你使用 print()
函数:
print(line, end='')
注意
你的 Getstatusoutput2()
方法会在 cmd
产生足够多的输出时阻塞,所以建议使用上面的解决方案:
>>> len(Getstatusoutput2(['python', '-c',"""print "*"*2**6"""])[1])
65
>>> len(Getstatusoutput2(['python', '-c',"""print "*"*2**16"""])[1])
等待子进程结束。设置并返回返回码属性。
警告:当使用 stdout=PIPE 和/或 stderr=PIPE,并且子进程生成的输出足够多以至于阻塞等待操作系统管道缓冲区接受更多数据时,这会导致死锁。使用 communicate() 可以避免这个问题。
相关内容 使用 communicate() 而不是 stdin.write()、stdout.read() 或 stderr.read()