Почему вывод политики apt-cache не передается по конвейеру?


12

Не могу понять почему

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

но

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

пустой.

Где в последнем звонке я делаю неправильное предположение?

Исходное задание: мне нужно обработать apt-cache policyвывод предположительно :-)

UPD :

fooиспользуемый в моем примере может быть заменен любым именем пакета, которого нет в вашем apt-getиндексе.

UPD 2 :

есть ответ с обходным путем. Дополнительная +50награда будет присуждаться любому, кто объясняет, почему 2>&1решение не работает.


# 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
Персидский залив

1
@MohsenPahlevanzadeh верно, теперь попробуйте точный вызов (имя пакета), который я предоставил :-)
zerkms

3
@MohsenPahlevanzadeh так? Извините, но вы уверены, что прочитали вопрос (и заголовок)?
zerkms

2
@MohsenPahlevanzadeh нет, это не равно (даже не близко)
zerkms

1
Я бегу, 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 (стандартный вывод) возникают проблемы. Я имею в виду, что это больше не написано в tty
Esref

Ответы:


11

Если stdout не является tty (т. Е. Это обычный файл или канал) и если --quietопция не указана, apt-cacheдействует так, как если бы вы ее передали --quiet=1. Обходной путь должен передать это --quiet=0выбор.

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


10

Кажется, есть некоторое обманчивое поведение для перенаправлений в apt-cache. Но мы можем обмануть мошенника, поменяв stdout и stderr !

Попробуйте это, оно должно работать:

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

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 (стандартный вывод), 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");

Ладно. Есть ли способ поймать их обоих?
zerkms

1
Я не мог найти ничего, кроме как ответ @ Mr_Mig. (Мой был apt-cache policy foo 1>&2 2>&1 | grep .) Но я нахожу, что в исходном коде apt apt-cache :) // Работа с stdout не является tty if (! Isatty (STDOUT_FILENO) && _config-> FindI ("quiet", -1) == - 1) _config-> Set ("quiet", "1");
Esref

Кстати, кто-то также указал мне на ту же точку в источниках всего несколько минут назад :-) И потенциально лучшее решение, script -c "sudo apt-cache policy foo" | grep Unableкоторое требует установки scriptхотя. Как и советовали - я поставлю +50 здесь через 2 дня (SE не позволяет делать это раньше)
zerkms

2
@Esref Ваш комментарий о "Я считаю, что в исходном коде apt apt-cache ..." должен быть в ответе, поэтому, пожалуйста, добавьте его туда. +1. :
Фахим Митха

О боже, больше нет варианта +50 щедрости :-(
zerkms

3

«Лучшим» решением было бы использовать scriptутилиту:

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

Таким образом он перехватывает весь вывод и передает его в stdout.

Единственным недостатком является то, что вам нужно установить, scriptесли у вас его еще нет. В Ubunty это предоставляется bsdutilsпакетом.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.