Dlaczego dane wyjściowe zasad apt-cache nie są przesyłane strumieniowo?

12

Nie mogę zrozumieć dlaczego

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

ale

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

jest pusty.

Gdzie w tym drugim wezwaniu robię błędne założenie?

Oryginalne zadanie: apt-cache policyprawdopodobnie przetwarzam dane wyjściowe :-)

UPD :

fooużyte w moim przykładzie można zastąpić dowolną nazwą pakietu, która nie istnieje w twoim apt-getindeksie.

UPD 2 :

istnieje odpowiedź z obejściem. Dodatkowa +50nagroda zostanie przyznana każdemu, kto wyjaśni, dlaczego 2>&1rozwiązanie nie działa.

zerkms
źródło
# 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 to prawda, teraz wypróbuj dokładnie wywołanie (nazwa pakietu), które
podałem
3
@MohsenPahlevanzadeh so? Przepraszam, ale czy na pewno przeczytałeś pytanie (i tytuł)?
zerkms
2
@MohsenPahlevanzadeh nie jest równy (nawet nie blisko)
zerkms
1
Uruchamiam strace apt-cache policy foo 2>&1i jest wywołanie systemowe, ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0które myślę, że z powodu tego połączenia 1 (standardowe wyjście) ma problemy. Mam na myśli, że nie jest już napisany do tty
Esref

Odpowiedzi:

11

Jeśli stdout nie jest tty (tzn. Jest zwykłym plikiem lub potokiem) i jeśli nie --quietokreślono żadnej opcji, apt-cachedziała tak, jakbyś ją przeszedł --quiet=1. Obejściem jest podanie --quiet=0opcji.

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo
Mark Plotnick
źródło
|&golfa 2>&1 |:-)
Ciro Santilli 26 改造 中心 法轮功 六四 事件
10

Wygląda na to, że istnieją pewne oszukańcze zachowania dotyczące przekierowań w apt-cache. Ale możemy oszukiwać oszusta, zamieniając stdout i stderr !

Wypróbuj ten, powinien działać:

apt-cache policy foo 3>&1 1>&2 2>&3 3>&- | grep .
Mr_Mig
źródło
7

Jeśli uruchomisz strace apt-cache policy foo 2>&1polecenie, zobaczysz linięioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

Ponieważ to polecenie manipuluje 1 (standardowe wyjście), 1 nie jest już zapisywane w standardowe wyjście. A jeśli przekierujesz 2 na 1, stracisz oba.

Edycja: Oto przykładowy kod z kodu źródłowego apt-cache:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");
Esref
źródło
W porządku. W jakiś sposób uchwycić ich obu?
zerkms
1
Nie mogłem znaleźć innego sposobu niż odpowiedź @ Mr_Mig. (Mój był apt-cache policy foo 1>&2 2>&1 | grep .) Ale znajduję to w kodzie źródłowym apt apt-cache :) // Zajmij się tym, że stdout nie jest tty, jeśli (! Isatty (STDOUT_FILENO) && _config-> FindI ("quiet", -1) == - 1) _config-> Set („quiet”, „1”);
Esref
Przy okazji, kilka minut temu ktoś też wskazał mi ten sam punkt w źródłach :-) I potencjalnie lepsze rozwiązanie, script -c "sudo apt-cache policy foo" | grep Unablektóre wymaga instalacji script. Zgodnie z zaleceniem - umieszczę tutaj +50 za 2 dni (SE nie pozwala na to wcześniej)
zerkms
2
@Esref Twój komentarz na temat „Uważam, że w kodzie źródłowym apt apt-cache ...” powinien znajdować się w odpowiedzi, więc dodaj go tam. +1. :
Faheem Mitha
O Boże, nie ma już opcji nagrody +50 :-(
Zerkms
3

„Lepszym” rozwiązaniem byłoby użycie scriptnarzędzia:

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

W ten sposób przechwytuje wszystkie dane wyjściowe i przekazuje je do stdout.

Jedyną wadą jest to, że musisz zainstalować, scriptjeśli jeszcze go nie masz. W Ubunty jest dostarczany przez bsdutilspakiet.

zerkms
źródło