Чому висновок політики apt-кеш-політики не передбачений?


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
PersianGulf

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 (stdout) має проблеми. Я маю на увазі, що це більше не написано на tty
Есреф

Відповіді:


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 (stdout), 1 більше не пишеться в stdout. І якщо ви переспрямовуєте 2 на 1, ви втратили їх обох.

Редагувати: Ось деякий зразок коду з вихідного коду apt-кеша:

// 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, якщо (! Isatty (STDOUT_FILENO) && _config-> FindI ("тихо", -1) == - 1) _config-> Set ("тихо", "1");
Есреф

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

2
@Esref Ваш коментар про "Я вважаю, що у вихідному коді apt apt-cache ..." має бути відповідь, тому будь ласка, додайте його туди. +1. :
Faheem Mitha

О боже, більше не існує +50
виграшних

3

"Кращим" рішенням буде використання scriptутиліти:

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

Таким чином він перехоплює весь вихід і пересилає його до stdout.

Єдиним недоліком є ​​те, що вам потрібно встановити, scriptякщо у вас його ще немає. В убутті це передбачено bsdutilsпакетом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.