【发布时间】:2016-02-29 21:45:29
【问题描述】:
[已编辑]
处理来自subprocess.Popen 的标准输出的两个选项是stdout="a_file_name" 和stdout=subprocess.PIPE。stderr 可以通过stderr=subprocess.STDOUT 与其中任何一个组合。
对于我目前正在做的事情(模糊测试),我生成的 stdout="a_file_name" 代码略短且更清晰。
但是,据我所见,stdout=PIPE 似乎经常受到其他人的青睐,但我不确定所有原因。
如果Popen([cmd, arg], ...) 中使用的cmd 是一个将错误输出写入stderr 的外部可执行文件,那么stdout=PIPE 是否比stdout="a_file_name" 更好?
各有什么优缺点?
- 在我的特定上下文中(参见下面的代码 sn-ps),我可以看到使用
stdout=PIPE而不是stdout="a_file_name"的一个优势是前者可以让我轻松跳过写入空文件。 - 如果发生
cmd崩溃,是否可能 2 个中的 1 个更有可能获得所有错误输出?
虽然我有自己的特定背景,但我也有兴趣了解更一般情况的答案。
为了更好地解释我的上下文,这里是我的 2 个替代代码段:
import subprocess
import sys
assert sys.version_info >= (3, 3)
# timeout added for subprocess's wait() and communicate() in Python 3.3.
with open('sub_proc1.outerr', 'w') as f_outerr1:
sub_proc1 = subprocess.Popen([cmd, args], stdout=f_outerr1,
stderr=subprocess.STDOUT,
universal_newlines=True)
try:
return_code = sub_proc1.wait(timeout=10)
print('*** %s CRASHED with return code: %d.' % (cmd, return_code))
except subprocess.TimeoutExpired:
print('*** %s succeeded.' % cmd)
sub_proc1.kill()
对比:
...
with open('sub_proc2.outerr', 'w') as f_outerr2:
sub_proc2 = subprocess.Popen([cmd, args], stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
try:
(sub_proc2_out, sub_proc2_err) = sub_proc2.communicate(timeout=10)
print('*** %s CRASHED with return code: %d.' %
(cmd, sub_proc2.poll()))
assert sub_proc2_err is None
# Since stderr was redirected to STDOUT, this should be None.
f_outerr2.write(str(sub_proc2_out or ""))
# Treat 'None' as an empty string).
except subprocess.TimeoutExpired:
print('*** %s succeeded.' % cmd)
sub_proc2.kill()
原帖:
TITLE:子流程:stderr=STDOUT 与 stderr=PIPE 的优缺点?
处理来自 'subprocess.Popen' 似乎是 'stderr=STDOUT' (与 'stdout="some_file"') 和 'stderr=PIPE'。
对于我想做的事情(模糊测试),我得到的“stderr=STDOUT” 代码更短更简洁。
但是,根据我的阅读,“stderr=PIPE”似乎是 首选,但我不确定所有原因。
如果使用的“cmd”是写入错误输出的外部可执行文件 对于“stderr”,使用“stderr=STDOUT”的优缺点是什么 与“stderr=PIPE”相比?
...
【问题讨论】:
-
如果您在测试程序中没有对输出(除了写入文件)做任何事情,我认为这两个代码之间没有太大区别。如果您想检查输出的实际细节(例如,将其包含在您的
print调用中,或者检查它是否写出特定的字符串),那么使用PIPE将是必要的。第一个代码的一个可能优点是,如果正在运行的程序交替写入它们,它将为您交错 stdout 和 stderr 流。另一方面,您无法区分这两个输出! -
感谢您的有用评论,Blckknght。如果我想检查输出的实际细节,我可以看到 PIPE 将是更好的选择。在我的特定上下文中,交错的 stdout 和 stderr 流很好。
-
您的评论让我意识到了一些我以前没有意识到的事情。这种交错可以使用任一方法进行:stdout="a_file_name", stderr=subprocess.STDOUT 或 stdout=subprocess.PIPE, stderr=subprocess.STDOUT 同样,使用任一方法也可以使 stdout 和 sterrr 流非交错:stdout ="file_name_1", stderr="file_name_2" 或 stdout=subprocess.PIPE, stderr=subprocess.PIPE
-
因此,我更新了我的帖子及其标题以反映 2 个交错选项: - 新标题:对于 subprocess.stderr=STDOUT - stdout=PIPE 是否优于 stdout="a_file_name"?
标签: python subprocess stdout popen stderr