Pourquoi la sortie de la stratégie apt-cache n'est-elle pas canalisée?

12

Je ne comprends pas pourquoi

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

mais

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

est vide.

Où dans ce dernier appel suis-je en train de faire l'hypothèse erronée?

La tâche d'origine: j'ai apt-cache policyprobablement besoin de traiter la sortie :-)

UPD :

fooutilisé dans mon exemple peut être remplacé par n'importe quel nom de package qui n'existe pas dans votre apt-getindex.

UPD 2 :

il y a une réponse avec une solution de contournement. Une +50prime supplémentaire sera accordée à toute personne qui explique pourquoi la 2>&1solution ne fonctionne pas.

zerkms
la source
# 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 c'est vrai, essayez maintenant l'appel exact (nom du package) que j'ai fourni :-)
zerkms
3
@MohsenPahlevanzadeh alors? Je suis désolé, mais êtes-vous sûr d'avoir lu la question (et le titre)?
zerkms
2
@MohsenPahlevanzadeh non ce n'est pas égal (même pas proche)
zerkms
1
Je cours strace apt-cache policy foo 2>&1et il y a un appel système, ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0je pense que cet appel 1 (stdout) a des problèmes. Je veux dire qu'il n'est plus écrit sur tty
Esref

Réponses:

11

Si stdout n'est pas un tty (c'est-à-dire un fichier normal ou un canal) et si aucune --quietoption n'a été spécifiée, apt-cacheagit comme si vous l'aviez passé --quiet=1. Une solution de contournement consiste à lui passer une --quiet=0option.

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo
Mark Plotnick
la source
|&golfs 2>&1 |:-)
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
10

Il semble y avoir un comportement tricheur pour les redirections dans apt-cache. Mais nous pouvons tromper un tricheur en échangeant stdout et stderr !

Essayez celui-ci, cela devrait fonctionner:

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

Si vous exécutez la strace apt-cache policy foo 2>&1commande, vous pouvez voir la ligneioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

Parce que cette commande manipule le 1 (stdout), 1 n'est plus écrit sur stdout. Et si vous redirigez 2 vers 1, vous les avez perdus tous les deux.

Edit: Voici un exemple de code à partir du code source apt-cache:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");
Esref
la source
D'accord. Une façon de les capturer tous les deux?
zerkms
1
Je n'ai pas pu trouver d'autre moyen que d'aimer la réponse de @ Mr_Mig. (Le mien l'était apt-cache policy foo 1>&2 2>&1 | grep .) Mais je trouve que dans le code source apt apt-cache :) // Traite avec stdout n'étant pas un tty si (! Isatty (STDOUT_FILENO) && _config-> FindI ("quiet", -1) == - 1) _config-> Set ("silencieux", "1");
Esref
Btw, j'ai également été pointé par quelqu'un au même point dans les sources il y a quelques minutes :-) Et une solution potentiellement meilleure script -c "sudo apt-cache policy foo" | grep Unablequi nécessite l'installation d'un scriptbien. Comme conseillé - je mettrai +50 ici dans 2 jours (SE ne laisse pas le faire plus tôt)
zerkms
2
@Esref Votre commentaire sur "Je trouve que dans le code source apt apt-cache ..." devrait être dans la réponse, alors veuillez l'ajouter ici. +1. :
Faheem Mitha
Oh mon dieu, il n'y a plus d'option de prime de +50 :-(
zerkms
3

Une "meilleure" solution serait d'utiliser un scriptutilitaire:

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

De cette façon, il intercepte toutes les sorties et les transmet au stdout.

Le seul inconvénient est que vous devez installer le scriptsi vous ne l'avez pas encore. En ubunty, il est fourni par bsdutilspaquet.

zerkms
la source