Por que a saída da política do apt-cache não é canalizada?

12

Não consigo entender o porquê

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

mas

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

está vazia.

Onde, na última chamada, estou fazendo a suposição errada?

A tarefa original: eu preciso processar a apt-cache policysaída presumivelmente :-)

UPD :

foousado no meu exemplo pode ser substituído por qualquer nome de pacote que não exista no seu apt-getíndice.

UPD 2 :

há uma resposta com uma solução alternativa. +50Recompensa adicional será concedida a quem explicar por que a 2>&1solução não funciona.

zerkms
fonte
# 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 isso mesmo, agora tente a chamada exato (nome do pacote) que eu forneci :-)
zerkms
3
@MohsenPahlevanzadeh so? Sinto muito, mas você tem certeza que leu a pergunta (e o título)?
Zerkms
2
@MohsenPahlevanzadeh não não é igual (nem perto)
zerkms
1
Eu corro strace apt-cache policy foo 2>&1e há uma chamada do sistema ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0, acho que por causa dessa chamada 1 (stdout) tem problemas. Quero dizer que não é escrito para tty mais
Esref

Respostas:

11

Se stdout não for um tty (ou seja, é um arquivo comum ou um canal) e se nenhuma --quietopção foi especificada, apt-cacheage como se você a tivesse passado --quiet=1. Uma solução alternativa é passar uma --quiet=0opção para ela .

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo
Mark Plotnick
fonte
|&golfs 2>&1 |:-)
Ciro Santilli escreveu
10

Parece haver algum comportamento barato para redirecionamentos no apt-cache. Mas podemos enganar um trapaceiro trocando stdout e stderr !

Experimente este, ele deve funcionar:

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

Se você executar o strace apt-cache policy foo 2>&1comando, poderá ver a linhaioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

Como esse comando manipula o 1 (stdout), 1 não é mais gravado no stdout. E se você redirecionar 2 para 1, você perdeu os dois.

Edit: Aqui está um exemplo de código do código-fonte do apt-cache:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");
Esref
fonte
OK. Alguma maneira de capturar os dois?
zerkms
1
Não encontrei outra maneira senão a resposta do @ Mr_Mig. (O meu era apt-cache policy foo 1>&2 2>&1 | grep .) Mas acho que no código fonte o apt apt-cache :) // Lida com o stdout não sendo um tty if (! Isatty (STDOUT_FILENO) && _config-> FindI ("quiet", -1) == - 1) _config-> Set ("quiet", "1");
Esref
Btw, eu também fui apontado por alguém para o mesmo ponto nas fontes apenas alguns minutos atrás :-) E uma solução potencialmente melhor script -c "sudo apt-cache policy foo" | grep Unableque requer a instalação de um scriptarquivo. Conforme recomendado - colocarei +50 aqui em 2 dias (o SE não permite fazer isso antes)
zerkms
2
@Esref Seu comentário sobre "Acho que no código fonte apt apt-cache ..." deve estar na resposta, então adicione-o lá. +1. :
Faheem Mitha
Oh Deus, não há mais +50 opções de recompensa :-(
zerkms
3

Uma solução "melhor" seria usar um scriptutilitário:

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

Dessa forma, ele intercepta toda a saída e a encaminha para o stdout.

A única desvantagem é que você precisa instalar o scriptse ainda não o tiver. No ubunty é fornecido pelo bsdutilspacote.

zerkms
fonte