【问题标题】:Why are subprobess.call() and subprocess.Popen printing when they're not supposed to?为什么 subprobess.call() 和 subprocess.Popen 不应该打印?
【发布时间】:2025-12-26 07:10:12
【问题描述】:

我正在尝试为 Ubuntu 创建一个 python 安装脚本。我试图通过创建脚本来自动化它,而不是输入所有的下载和编译命令。我真正想做的是不打印命令的所有输出,只输出错误,并将常规输出打印到文件中。

我阅读了this * 指南和this python 文档,但有些东西我无法弄清楚。每当我将 call 和 Popen 的 stdout 参数设置为 None 时,它​​仍然会将输出打印到 shell,根据 python 文档,这不应该发生。

例如,假设我们在一个包含几个文件“a”、“b”和“c”的目录中。根据 python 文档,以下命令应该只输出 0。

>>> subprocess.call(["ls", "-a"])
0

但我不明白。相反,我得到了输出:

>>> subprocess.call(['ls', '-a'])
.  ..  a  b  c
0

我尝试将 stdout 参数设置为 None,但它仍在打印输出,这是不对的。 Subprocess.Popen 具有相同的行为。如何让 python 不打印输出?

为了记录,我正在运行带有 python 3.4.0 的 Ubuntu 14.04 64 位。

编辑:我也从文件内部尝试了上述方法并执行了文件,但我仍然得到不正确的行为。

【问题讨论】:

  • 据我了解您的问题,您想从 python 文件运行命令吗?然后输出到文件,如果出错,在命令行显示?
  • @smushi,是的,没错。

标签: python subprocess


【解决方案1】:

您应该仔细阅读文档;来自subprocess.call

完整的函数签名与 Popen 构造函数的签名相同 [...]

来自subprocess.Popen

默认设置为None,不会发生重定向;子文件句柄将从父文件继承。

因此,一般而言,将stdout 设置为None 与将其设置为subprocess.STDOUT 一样。如果需要抑制输出设置为subprocess.DEVNULL,或者存储在输出文件中,只需将打开的文件对象设置为参数即可。

要捕获和处理输出,请使用subprocess.check_output

【讨论】:

  • +1 用于文档参考。不要设置stdout=STDOUT(这是一个错误)。只有stderr=STDOUT 有意义。
  • @Arpegius 谢谢,我读的时候不太明白这是什么意思。
  • @wheeler cmets 中不需要坦克。请点击绿色复选标记接受我的回答。
【解决方案2】:

None 表示继承父级的标准流。将 stdout 重定向到文件并允许 stderr 继续打印到 shell(如果父级的 stderr 打印到 shell):

import subprocess

with open('your_script.log', 'a') as logfile:
    subprocess.check_call(['ls', '-a'], stdout=logfile)

【讨论】: