¿Por qué no se canaliza la salida de la política de apt-cache?

12

No puedo entender por qué

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

pero

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

esta vacio.

¿Dónde en la última llamada estoy haciendo la suposición equivocada?

La tarea original: necesito procesar la apt-cache policysalida presumiblemente :-)

UPD :

fooutilizado en mi ejemplo puede ser sustituido por cualquier nombre de paquete que no exista en su apt-getíndice.

UPD 2 :

Hay una respuesta con una solución alternativa. Se +50otorgará una recompensa adicional a cualquiera que explique por qué la 2>&1solución no funciona.

zerkms
fuente
# 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 es cierto, ahora intente la llamada exacta (nombre del paquete) que proporcioné :-)
zerkms
3
@MohsenPahlevanzadeh entonces? Lo siento, pero ¿estás seguro de haber leído la pregunta (y el título)?
zerkms
2
@MohsenPahlevanzadeh no es igual (ni siquiera cerca)
zerkms
1
Corro strace apt-cache policy foo 2>&1y hay una llamada al sistema ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0, creo que debido a esta llamada 1 (stdout) tiene problemas. Quiero decir que ya no está escrito en tty
Esref

Respuestas:

11

Si stdout no es un tty (es decir, es un archivo normal o una tubería) y si no --quietse ha especificado ninguna opción, apt-cacheactúa como si la hubiera pasado --quiet=1. Una solución alternativa es pasarle una --quiet=0opción.

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

Parece que hay un comportamiento engañoso para las redirecciones apt-cache. ¡Pero podemos engañar a un tramposo intercambiando stdout y stderr !

Prueba este, debería funcionar:

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

Si ejecuta el strace apt-cache policy foo 2>&1comando, puede ver la líneaioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

Debido a que ese comando manipula el 1 (stdout), 1 ya no se escribe en stdout. Y si redirige 2 a 1, los perdió a ambos.

Editar: Aquí hay un ejemplo de código del código fuente de apt-cache:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");
Esref
fuente
Bueno. ¿Alguna forma de capturarlos a ambos?
zerkms
1
No pude encontrar otra forma que no sea la respuesta de @ Mr_Mig. (El mío era apt-cache policy foo 1>&2 2>&1 | grep .) Pero me parece que en el código fuente apt apt-cache :) // Tratar con stdout no es un tty if (! Isatty (STDOUT_FILENO) && _config-> FindI ("quiet", -1) == - 1) _config-> Set ("quiet", "1");
Esref
Por cierto, alguien me señaló el mismo punto en las fuentes hace solo unos minutos :-) Y una solución potencialmente mejor script -c "sudo apt-cache policy foo" | grep Unableque requiere la instalación de un scriptdispositivo. Según lo aconsejado - pondré +50 aquí en 2 días (SE no permite hacerlo antes)
zerkms
2
@Esref Tu comentario sobre "Me parece que en el código fuente apt apt-cache ..." debería estar en la respuesta, así que agrégalo allí. +1. :
Faheem Mitha
Oh dios, ya no hay opción de recompensa +50 :-(
zerkms
3

Una solución "mejor" sería utilizar una scriptutilidad:

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

De esa manera intercepta toda la salida y la reenvía a stdout.

El único inconveniente es que necesita instalar el scriptsi aún no lo tiene. En ubunty se proporciona por bsdutilspaquete.

zerkms
fuente