Hoy tuve la necesidad de listar paquetes por repositorio en un servidor Debian 6. Determinar qué paquetes fueron instalados desde un repositorio en particular. Descubrí que no es una tarea sencilla en absoluto. Por ello decidí escribir este breve artículo, para tener a mano el comando en caso de necesitar utilizarlo en el futuro.

En Debian y derivados, normalmente se utiliza el comando dpkg -l | grep '^ii' para listar los paquetes instalados. Aunque la salida de este comando no contiene información acerca de qué repositorio proviene cada paquete. La herramienta apt-cache provee dicha información, pero no permite listar paquetes por repositorio, por lo tanto sólo es posible filtrar manualmente.

Veamos un ejemplo en un sistema Debian 6:

root@debian6:~# cat /etc/issue
Debian GNU/Linux 6.0 \n \l

Cuando se me planteó esta necesidad, la primera opción que probé fue utilizar la herramienta dpkg-query, la cual, según su página de manual, posee la opción -W para listar todos los paquetes (cuando no se especifica ningún patrón), y la opción -f para formatear su salida:

root@debian6:~# man dpkg-query
       -W, --show package-name-pattern...
              Just like the --list option this will list all packages  match-
              ing  the  given  pattern.  However the output can be customized
              using the --showformat option.  The default output format gives
              one  line  per  matching package, each line having the name and
              installed version of the package, separated by a tab.
       -f, --showformat=format
              This option is used to specify the format of the output  --show
              will  produce.  The  format is a string that will be output for
              each package listed.

Y entre las opciones de formato es posible obtener el origen (repositorio) de cada paquete:

                  Maintainer
                  Origin
                  Package

Lamentablemente descubrí que, a pesar de que se dispone de esta opción, no existe la información:

root@debian6:~# dpkg-query -W -f='${Package} ${Origin}\n' | head
acpi 
acpi-support-base 
acpid 
adduser 
aide 
aide-common 
apache2 
apache2-mpm-worker 
apache2-threaded-dev 
apache2-utils 

En cambio sí existe para otros campos:

root@debian6:~# dpkg-query -W -f='${Package} ${Maintainer}\n' | head
acpi Debian Acpi Team <pkg-acpi-devel@lists.alioth.debian.org>
acpi-support-base Debian Acpi Team <pkg-acpi-devel@lists.alioth.debian.org>
acpid Debian Acpi Team <pkg-acpi-devel@lists.alioth.debian.org>
adduser Debian Adduser Developers <adduser-devel@lists.alioth.debian.org>
aide Aide Maintainers <pkg-aide-maintainers@lists.alioth.debian.org>
aide-common Aide Maintainers <pkg-aide-maintainers@lists.alioth.debian.org>
apache2 Debian Apache Maintainers <debian-apache@lists.debian.org>
apache2-mpm-worker Debian Apache Maintainers <debian-apache@lists.debian.org>
apache2-threaded-dev Debian Apache Maintainers <debian-apache@lists.debian.org>
apache2-utils Debian Apache Maintainers <debian-apache@lists.debian.org>

Por lo tanto debí probar otra solución: obtener el listado de todos los paquetes instalados y ejecutar apt-cache show sobre cada uno, para luego filtrar por repositorio. Por ejemplo, si quisiera determinar qué paquetes han sido instalados desde el repositorio "lts" simplemente debo ejecutar:

root@debian6:~# for p in $(dpkg -l | grep '^ii' | cut -d ' ' -f 3); do apt-cache showpkg $p | head -3 | grep -v '^Versions' | sed -e 's/Package: //;' | paste - - ; done | grep lts | awk -F '\t' '{print $1}' | head
acpi-support-base
apache2
apache2-mpm-worker
apache2-threaded-dev
apache2-utils
apache2.2-bin
apache2.2-common
apt
apt-utils
bash

En el sistema en cuestión, 34 paquetes (instalados) provienen del repositorio "backports":

root@debian6:~# for p in $(dpkg -l | grep '^ii' | cut -d ' ' -f 3); do apt-cache showpkg $p | head -3 | grep -v '^Versions' | sed -e 's/Package: //;' | paste - - ; done | grep backports | wc -l
34

¿Qué hace éste comando?

for p in $(dpkg -l | grep '^ii' | cut -d ' ' -f 3); do apt-cache showpkg $p | head -3 | grep -v '^Versions' | sed -e 's/Package: //;' | paste - - ; done | grep lts | awk -F '\t' '{print $1}'

Primero obtiene un listado de todos los paquetes instalados quedándose sólo con el nombre del paquete: dpkg -l | grep '^ii' | cut -d ' ' -f 3

Luego, para cada uno (for p in $), obtiene su información detallada: apt-cache showpkg $p

En la salida de apt-cache showpkg, la primera línea es el nombre del paquete y de la tercera se puede deducir el origen. Por ende, se obtienen sólo las primeras 3 líneas (head -3), se elimina la segunda línea (grep -v '^Versions'), se elimina la cadena "Package: " de la primera línea (sed -e 's/Package: //;'), y se concatenan ambas líneas (paste - -).

Hasta aquí se obtiene un listado donde cada línea posee el nombre del paquete y su origen. Sólo resta filtrar de acuerdo al repositorio deseado, por ejemplo "lts" (grep lts), "backports", "updates", etc. Luego es posible quedarse sólo con los nombres de paquete (awk -F '\t' '{print $1}') o con el total (wc -l).

De esta forma fui capaz de identificar qué paquetes fueron instalados desde el repositorio "lts".

Espero que les sirva.


Tal vez pueda interesarte


Compartí este artículo