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

zer*_*kms 13 shell pipe apt

不明白为什么

$ apt-cache policy foo
N: Unable to locate package foo
Run Code Online (Sandbox Code Playgroud)

$ apt-cache policy foo 2>&1 | grep .
Run Code Online (Sandbox Code Playgroud)

是空的。

在后一个电话中我在哪里做错误的假设?

原始任务:我apt-cache policy大概需要处理输出:-)

更新

foo在我的例子中使用可以与任何包名称替代不存在在你的apt-get指数。

更新 2

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

Mar*_*ick 12

如果 stdout 不是一个 tty(即它是一个普通文件或管道)并且如果没有--quiet指定选项,则apt-cache表现为你已经通过了它--quiet=1。一种解决方法是向它传递一个--quiet=0选项。

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo
Run Code Online (Sandbox Code Playgroud)


小智 10

中的重定向似乎有一些作弊行为apt-cache。但是我们可以通过交换 stdout 和 stderr来欺骗骗子!

试试这个,它应该可以工作:

apt-cache policy foo 3>&1 1>&2 2>&3 3>&- | grep .
Run Code Online (Sandbox Code Playgroud)


Esr*_*ref 7

如果你运行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 不再写入标准输出。如果你将 2 重定向到 1,你就会失去它们两个。

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

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

  • @Esref 您对“我发现在源代码中 apt apt-cache ...”的评论应该在答案中,所以请在那里添加。+1。: (2认同)