对于 subprocess.stderr=STDOUT - stdout=PIPE 是否优于 stdout="a_file_name"?

For subprocess.stderr=STDOUT - Is stdout=PIPE better than stdout="a_file_name"?

[已编辑]
处理来自 subprocess.Popen 的标准输出的 2 个选项是 stdout="a_file_name"stdout=subprocess.PIPE.
stderr 可以通过 stderr=subprocess.STDOUT.

与其中任何一个组合

对于我目前正在做的事情(模糊测试),我得到的 stdout="a_file_name" 代码稍微更短更清晰。

然而,据我所见,stdout=PIPE 似乎经常受到其他人的青睐,但我不确定所有原因。

如果 Popen([cmd, arg], ...) 中使用的 cmd 是将错误输出写入 stderr 的外部可执行文件,那么 stdout=PIPEstdout="a_file_name"?

各自的优缺点是什么?

虽然我有自己的特定背景,但我也有兴趣知道更一般情况下的答案。

为了更好地解释我的上下文,这里是我的 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()

原版POST:

TITLE: subprocess: Pros and cons of stderr=STDOUT vs. stderr=PIPE?

The 2 principal alternatives for handling error output from 'subprocess.Popen' seem to be 'stderr=STDOUT' (with 'stdout="some_file"') and 'stderr=PIPE'.

For what I want to do (fuzz-testing), my resulting 'stderr=STDOUT' code is a little shorter and cleaner.

However, from what I've read, it seems that 'stderr=PIPE' is preferred, but I'm not sure of all of the reasons why.

If the 'cmd' used is an external executable which writes error output to 'stderr', what are the pros and cons of using 'stderr=STDOUT' versus 'stderr=PIPE'?

...

写入特定文件意味着如果您的程序一次 运行 多次,则会发生冲突,因为两个进程都希望写入同一个文件。 (搜索临时文件创建问题和安全漏洞)

使用管道意味着不存在文件名唯一性的问题。

你关心输出吗?如果不是,则使用 subprocess.DEVNULL,它将为您丢弃输出。