Python:获取非零退出码命令行的输出
我在一台运行 Windows Server 2008 R2 x64 的机器上使用 Python 2.7.1
。
我想获取一个命令行程序的输出,但这个程序在输出我需要的信息后返回了一个非零的退出状态。
我最开始使用的是 subprocess.check_output
,并捕获了因为非零退出状态而产生的 CalledProcessError 错误,但错误中虽然存储了返回码,却没有显示任何输出。
对于那些输出正常但退出状态为 0 的情况,运行是没问题的,我可以通过 subprocess.check_output 获取到输出。
我猜测输出是写入了标准输出(STDOUT),但异常却从标准错误(STDERR)中提取了“输出”。我尝试重新实现 check_output 的功能,但在我认为应该看到标准输出和标准错误的输出时,仍然什么都没有。下面是我当前的代码(其中 'command' 是我运行的命令的完整文本,包括参数):
process = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, universal_newlines=True)
output = process.communicate()
retcode = process.poll()
if retcode:
raise subprocess.CalledProcessError(retcode, image_check, output=output)
return output
这让我在变量 output 中得到了以下内容: [('', None)]
我的 subprocess.Popen
代码是正确的吗?
3 个回答
这里有一个可能会影响到你的问题——http://bugs.python.org/issue9905
你有没有试过用 stderr=subprocess.STDOUT
,这个在Python的文档页面上提到过:
如果你想把标准错误也一起捕获到结果中,可以使用 stderr=subprocess.STDOUT:
下面是一个测试代码:
import subprocess
try:
subprocess.check_output('>&2 echo "errrrr"; exit 1', shell=True)
except subprocess.CalledProcessError as e:
print 'e.output: ', e.output
try:
subprocess.check_output('>&2 echo "errrrr"; exit 1', shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print 'e.output: ', e.output
输出结果:
errrrr
e.output:
e.output: errrrr
你的代码运行得很好。结果发现,你调用的那个过程可能是输出到 CON(控制台)。看看下面这个例子:
import subprocess
def check_output(command):
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
output = process.communicate()
retcode = process.poll()
if retcode:
raise subprocess.CalledProcessError(retcode, command, output=output[0])
return output
command = "echo this>CON"
print "subprocess -> " + subprocess.check_output(command, shell=True)
print "native -> " + str(check_output(command))
try:
subprocess.check_output("python output.py", shell=True)
except subprocess.CalledProcessError, e:
print "subproces CalledProcessError.output = " + e.output
try:
check_output("python output.py")
except subprocess.CalledProcessError, e:
print "native CalledProcessError.output = " + e.output
输出结果:
subprocess ->
native -> ('', None)
stderr subproces CalledProcessError.output = stdout
native CalledProcessError.output = stderr stdout
可惜,我不知道怎么解决这个问题。注意,subprocess.check_output
的结果只包含标准输出(stdout)的内容。而你替代的 check_output 会同时输出标准错误(stderr)和标准输出(stdout)。
经过检查,subprocess.check_output
确实会生成一个 CalledProcessError,并且输出只包含标准输出的内容。