Return 使用 shell 管道时 subprocess.run 的代码

Return code of subprocess.run when using shell pipes

我正在尝试理解 subprocess.run 的 return 代码:

>>> subprocess.run('false | true', shell=True)
CompletedProcess(args='false | true', returncode=0)
>>> subprocess.run(['false', '|', 'true'])
CompletedProcess(args=['false', '|', 'true'], returncode=1)
>>> subprocess.run(['false', '|', 'true'], shell=True)
CompletedProcess(args=['false', '|', 'true'], returncode=1)

看起来将 cmd 指定为字符串列表也会设置 pipefail shell 选项:

$ false | true
$ echo $?
0
$ set -o pipefail
$ false | true
$ echo $?
1

我在 subprocess 模块的文档中找不到任何关于此的信息。我正在使用 python 3.6。有谁知道这是如何工作的?

这和你想的不一样:

>>> subprocess.run(['false', '|', 'true'], shell=True)

当您将字符串列表传递给 subprocess.run 并指定 shell=True 时,只有第一项被解释为命令(其余项目作为参数提供给 shell ).比较输出:

>>> subprocess.run('echo hello world', shell=True)
hello world
CompletedProcess(args='echo hello world', returncode=0)

与:

>>> subprocess.run(['echo', 'hello', 'world'], shell=True)

CompletedProcess(args=['echo', 'hello', 'world'], returncode=0)

与:

>>> subprocess.run(['echo [=13=] ', 'hello', 'world'], shell=True)
hello world
CompletedProcess(args=['echo [=13=] ', 'hello', 'world'], returncode=0)

所以你所拥有的相当于:

>>> subprocess.run('false', shell=True)

And do you know why the return codes of subprocess.run('false | true', shell=True) and subprocess.run(['false', '|', 'true']) are different?

因为第一个运行false | true,这是一个管道。管道的退出代码是管道中最后一个命令的退出代码(在本例中为 true)。如此处所述,第二次调用仅运行 false.