apt-get install 输出在正常执行时和从 python 执行时的行为不同

apt-get install output behaves differently when executed normally and from python

我今天注意到 apt 的行为不同,具体取决于它来自 运行 的位置 (shell / python / ...)。

背景 我试图通过 apt CLI 找出“watch”的提供包。这也非常适合手动操作:

apt-get install -s watch

NOTE: This is only a simulation!
  apt-get needs root privileges for real execution.
  Keep also in mind that locking is deactivated,
  so don't depend on the relevance to the real current situation!
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'procps' instead of 'watch'
procps is already the newest version (2:3.3.15-2).
procps set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 15 not upgraded.

重要的一行是Note, selecting 'procps' instead of 'watch':显然,watch 是由procps 提供的。到目前为止一切顺利。

当我从 python 的 subprocess 库中执行相同的命令时,这一行消失了。使用 os.system,它又开始工作了。

所以我试图通过简单地将命令行(stdout 和 stderr)的输出传输到日志文件中来调查这个问题 (apt-get install -s watch &> /tmp/output) 结果:

NOTE: This is only a simulation!
      apt-get needs root privileges for real execution.
      Keep also in mind that locking is deactivated,
      so don't depend on the relevance to the real current situation!
Reading package lists...
Building dependency tree...
Reading state information...
procps is already the newest version (2:3.3.15-2).
procps set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 15 not upgraded.

缺少该行。

之后我在 apt 的源代码中搜索了一下,找到了 corresponding line。这里的输出流是 out,其他一些 ioprintf 部分正在使用 c1out。所以这似乎是另一个流...但是为什么我的终端打印这个流的输出而大多数其他程序无法处理它?

你 运行 os.system 来自虚拟环境吗? 很有可能是因为这个。

apt 的行为根据其输出是否为 tty 而有所不同。

如果它的标准输出不是,它的行为就好像 --quiet=1 已传递给它。

您可以通过显式传递 --quiet=0 来省略该行为。

apt-get --quiet=0 install -s watch | less

手册页可以详细说明 --quiet。

请注意: 依赖 apt-developers 变得更难管道甚至 grep/awk 的东西很可能是个坏主意。