14

Cannot get why

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

but

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

is empty.

Where in the latter call am I doing the wrong assumption?

The original task: I need to process the apt-cache policy output presumably :-)

UPD:

foo used in my example may be substituted with any package name that does not exist in your apt-get index.

UPD 2:

there is an answer with a workaround. Additional +50 bounty will be awarded to anyone who explains why the 2>&1 solution does not work.

8
  • # apt-cache policy vim 2>&1 |grep . vim: Installed: 2:7.4.712-2 Candidate: 2:7.4.712-2 Version table: *** 2:7.4.712-2 0 500 http://ftp.debian.org/debian/ sid/main amd64 Packages 100 /var/lib/dpkg/status May 6, 2015 at 21:02
  • 1
    @MohsenPahlevanzadeh that's right, now try the exact call (package name) I provided :-)
    – zerkms
    May 6, 2015 at 21:03
  • 3
    @MohsenPahlevanzadeh so? I'm sorry, but are you sure you have read the question (and the title)?
    – zerkms
    May 6, 2015 at 21:06
  • 2
    @MohsenPahlevanzadeh not it's not equal (not even close)
    – zerkms
    May 6, 2015 at 21:09
  • 1
    I run strace apt-cache policy foo 2>&1 and there is a system call ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 I think because of this call 1(stdout) has problems. I mean it is not written to tty anymore
    – Esref
    May 6, 2015 at 22:16

4 Answers 4

13

If stdout is not a tty (i.e. it's a regular file or a pipe) and if no --quiet option has been specified, apt-cache acts as if you had passed it --quiet=1. A workaround is to pass it a --quiet=0 option.

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo
3
  • |& golfs 2>&1 | :-) Jul 26, 2015 at 8:41
  • I can't imagine what the developers of apt-cache were thinking when they decided to do this. Unless they wanted to confuse users, of course. In which case they've done a great job! Aug 27, 2021 at 17:46
  • @FabiosaysReinstateMonica —quiet is supposed to let you suppress progress messages. The decision in apt-cache to have it suppress error messages as well might be a bug. I’ll look. Aug 29, 2021 at 6:03
10

There seems to be some cheaty behavior for redirections in apt-cache. But we can cheat a cheater by swapping stdout and stderr!

Try this one, it should work:

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

If you run strace apt-cache policy foo 2>&1 command, you can see the line ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

Because that command manipulates the 1(stdout), 1 is not written to stdout anymore. And if you redirect 2 to 1, you lost both of them.

Edit: Here is a some code sample from apt-cache source code:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");
5
  • Okay. Any way to capture them both?
    – zerkms
    May 6, 2015 at 23:05
  • 1
    I could not find any way other than like @Mr_Mig's answer. (Mine was apt-cache policy foo 1>&2 2>&1 | grep .) But I find that in the source code apt apt-cache :) // Deal with stdout not being a tty if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1");
    – Esref
    May 7, 2015 at 0:39
  • Btw, I also was pointed by someone to the same point in sources just few minutes ago :-) And a potentially better solution script -c "sudo apt-cache policy foo" | grep Unable which requires installing a script though. As advised - I will put +50 here in 2 days (SE does not let to do it earlier)
    – zerkms
    May 7, 2015 at 0:55
  • 2
    @Esref Your comment about "I find that in the source code apt apt-cache..." should be in the answer, so please add it there. +1. : May 7, 2015 at 9:08
  • Oh god, there is no +50 bounty option anymore :-(
    – zerkms
    May 10, 2015 at 4:31
3

A "better" solution would be to use a script utility:

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

That way it intercepts all the output and forwards it to the stdout.

The only drawback is that you need to install the script if you don't have it yet. In ubunty it's provided by bsdutils package.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .