解释Python的子进程模块中bash的输出

Interpret output from bash in Python's subprocess module

我一直在阅读DougHelmann的Pymoptw上的subprocess模块示例。这是我遇到麻烦的代码片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# subprocess_run_output_error.py
import subprocess

try:
    completed = subprocess.run(
        'echo to stdout; echo to stderr 1>&2; exit 1',
        check=True,
        shell=True,
        stdout=subprocess.PIPE,
    )
except subprocess.CalledProcessError as err:
    print('ERROR:', err)
else:
    print('returncode:', completed.returncode)
    print('Have {} bytes in stdout: {!r}'.format(
        len(completed.stdout),
        completed.stdout.decode('utf-8'))
    )

我知道exit 1应该抛出一个错误,并运行except子句。

1
2
to stderr
ERROR: Command 'echo to stdout; echo to stderr 1>&2; exit 1' returned non-zero exit status 1.

我不明白为什么to stdout不是印刷品,而是to stderr印刷品。运行echo to stdout后,1>&2是否出现?

为了更好地理解,我修改了代码以查看是否可以运行else部分,所以我将其切换到exit 0。当我这样做时,我得到的输出是:

1
2
3
4
to stderr
returncode: 0
Have 10 bytes in stdout: 'to stdout
'

我似乎不明白1>2的意思,尽管它会作弊。

  • 又一次打印了to stderr。为什么to stdout自首次出现以来就没有首先打印出来?

  • 为什么CompletedProcess对象只对to stderr持有不是to stdout吗?

  • 如果我理解下面的作弊表部分,那么如果文件描述符是2,为什么不将to stderr发送到标准错误流?
  • n>&m # file descriptor n is made to be a copy of the output file
    descriptor

    我发现另一个相对接近的问题是这个。但是,它比较了&>>&。我无法理解最初的>&,所以我感到更加困惑。


  • 因为你捕获了它,所以你可以在completed.stdout上找到它。
  • 因为你只捕获了stdout:stdout=subprocess.PIPE,而没有stderr=subprocess.PIPE
  • 它实际上被发送到stderr,这就是为什么它在开始时被打印的原因,因为您没有捕获它,并且该流是未缓冲的。