为什么 apt-cache 策略输出不通过管道传输?

为什么 apt-cache 策略输出不通过管道传输?

不明白为什么

$ apt-cache policy foo
N: Unable to locate package foo

$ apt-cache policy foo 2>&1 | grep .

是空的。

在后一个调用中我在哪里做了错误的假设?

apt-cache policy最初的任务:我大概需要处理输出:-)

UPD:

foo我的示例中使用的可以替换为任何包名称不存在在你的apt-get索引中。

更新2:

有一个答案和解决方法。任何解释该解决方案不起作用+50的原因的人都将获得额外的赏金。2>&1

答案1

如果 stdout 不是 tty(即它是常规文件或管道)并且未--quiet指定任何选项,apt-cache则就像您已传递它一样--quiet=1。解决方法是向其传递一个--quiet=0选项。

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo

答案2

中的重定向似乎存在一些欺骗行为apt-cache。但我们可以通过以下方式欺骗骗子交换 stdout 和 stderr

试试这个,它应该有效:

apt-cache policy foo 3>&1 1>&2 2>&3 3>&- | grep .

答案3

如果运行strace apt-cache policy foo 2>&1命令,您可以看到这一行ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

因为该命令操作 1(stdout),所以 1 不再写入 stdout。如果你将 2 重定向到 1,你就会失去它们。

编辑:这是来自 apt-cache 源代码的一些代码示例:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");

答案4

一个“更好”的解决方案是使用一个script实用程序:

script -c "apt-cache policy foo" /dev/null | grep .

这样它会拦截所有输出并将其转发到stdout.

script唯一的缺点是,如果您还没有安装,则需要安装。在ubunty中它是由bsdutils包提供的。

相关内容