2.6.2. Gestión del software

La mayor parte del software del que se constituyen los sistemas linux es software libre, disponible en la red, de ahí que las distribuciones se encarguen de seleccionarlo, prepararlo y facilitarlo. debian no es una excepción y dispone de un sistema de paquetes .deb que facilitan la instalación, actualización y borrado del software.

Antes de nada es importante tener claros algunos conceptos:

Paquete

Es una colección de ficheros relacionados entre sí por constituir una aplicación o parte de una aplicación, entre los cuales pueden encontrarse documentos, configuraciones, bibliotecas o ejecutables. Esta colección está comprimida y empaqueta en un mismo fichero que en el caso de debian (y de todas sus distribuciones derivadas) es .deb 1.

Repositorio o réplica

Es un lugar (cdrom, servidor web, servidor ftp) donde se almacenan paquetes, con el propósito de que el usuario acceda a ellos y, de forma sencilla, los descargue e instale.

Gestor de paquetes

Es el sotfware encargado de gestionar la instalación, borrado y actualización de software.

Por lo general, las aplicaciones de software libre no son autosuficientes, sino que utilizan bibliotecas, también de software libre. Esto lleva a que entre unos y otros paquetes existan dependencias, de modo que para que un paquete se instalé es necesario que haya instalados antes otros paquetes que, a su vez, pueden requerir otros paquetes, etc. Esto crea una compleja de red de dependiencias que el gestor de paquetes se encarga de solucionar.

Advertencia

Este apartado es el más dependiente de la distribución hasta el punto de que es absolutamente inútil su lectura si no se utiliza una distribución basada en debian.

2.6.2.1. Vistazo general

Advertencia

Este subapartado, en concreto, es absolutamente inútil, a menos que se use debian. Si se utiliza una distribución basada en debian, pero no debian misma, sáltelo sin escrúpulo.

debian está dividida en tres grandes ramas:

  1. La distribución estable (stable) orientada al uso en servidores, durante cuya vida sólo recibe actualizaciones para correción de bugs y problemas de seguridad.

  2. La distribución en pruebas (testing), que se actualiza regularmente con nuevo software y versiones más recientes del software ya existente.

  3. La distribución inestable (unstable), que se actualiza aún con mayor celeridad y que sirve como alimentación a la rama en pruebas.

Por tradición2, las diferentes versiones de debian reciben el nombre de un personaje de la serie de películas de animación Toy Story. La actual estable, la versión 8, tiene por nombre Jessie; la de pruebas, Stretch; y la inestable es la única que no cambia su nombre y se llama siempre Sid (el chico que rompía los juguetes).

El ciclo de vida es el siguiente:

  1. La distribución inestable recibe constantemente paquetes con las últimas versiones de software.

  2. También constantemente, la rama en pruebas va recibiendo paquetes procedentes de la rama inestable, según se vea que no producen errores graves en el sistema.

  3. La rama estable, ajena a todas estas actualizaciones, mantiene las versiones de los paquetes con la que salió. Sólo recibe actualizaciones que corrijan problemas detectados.

  4. En un momento determinado (últimamente es cada dos años), se congela la rama en pruebas, de manera que deja de recibir actualizaciones de paquetes procedentes de sid y el equipo de desarrollo se centra en la tarea de eliminar bugs importantes. Este proceso es lento y suele llevar más de seis meses.

  5. Cuando no existen errores graves detectados, la rama estable pasa a ser la vieja estable (oldstable), y la rama en pruebas congelada se desdobla de manera que, por un lado, pasa a ser la estable, llevándose el nombre consigo; y, por otro, se rebautiza con un nuevo personaje de Toy Story y comienza de nuevo a admitir actualizaciones procedentes de sid.

  6. Por su parte, la vieja inestable sigue recibiendo soporte oficial de debian durante al menos tres años más, de manera que se llegue al menos a los cinco años de vida: los dos que tuvo como distribución estable y estos tres años adicionales de soporte.

Además de las tres distribuciones de desarrollo principales, existen otras tres de interés:

  1. La vieja estable (oldstable) que ya se ha explicado.

  2. La experimental, que no es una distribución completa, sino un repositorio de pruebas don de se sube software nuevo o versiones nuevas de software existente y que, por lo general, o no funciona o no lo hace totalmente, pero se incluye como paso previo a poder entrar en la distribución inestable.

  3. Los backports para la versión estable, que es un repositorio con software más moderno que aquel del que se dispone en la estable. Tengamos en cuenta que entre la fase de congelación y el tiempo que tenga ya como estable, nos podemos encontrar con software que tiene casi tres años de antigüedad. Obviamente, la estabilidad y seguridad de los paquetes de la backports no es comparable con la de aquellos que se encuentran en la estable, así que el administrador debe sopesar si elige actualiza a versiones más modernas corriendo el riesgo de encontrar bugs adicionales.

Por otro lado, dentro de una distribución los paquetes se distribuyen en tres componentes:

main

Paquetes que cumplen los requisitos para ser considerados por debian software libre y que, además, sólo tienen dependencia de paquetes que también pertenecen a este componente.

contrib

Paquetes que son software libre, pero tiene dependencia de paquetes que no son software libre.

non-free

Paquetes que no son software libre a criterio de debian.

2.6.2.2. Gestores de debian

Para el control de paquetes, debian dispone de algunas herramientas:

dpkg

No es propiamente un gestor, sino la herramienta básica para la instalación, borrado y actualización de un paquete y, consecuentemente, es utilizada por los gestores de los que se hablará a continuación.

La usaremos cuando deseemos información particular sobre algún paquete.

dselect

Fue el primer front-end para la gestión de paquetes. Apenas se usa ya.

aptitude

Como dselect provee de una interfaz para la gestión de paquetes, aunque la mayor parte de los usuarios lo utilice pasando directamente las opciones necesarias a través de la línea de comandos. De esta última forma, tiene muchas similitudes con apt-get. Tiene como ventaja sobre este último que es capaz de hacer sugerencias, cuando por algún problema de incompatibilidades no es posible instalar algún paquete o actualizar el sistema completo.

A partir de stretch no viene instalado de serie.

apt-*

Familia de órdenes (apt-get, apt-cache)) que gestiona paquetes desde la línea de comandos. Fue durante mucho tiempo el gestor más usado.

apt

La familia anterior tiene el inconveniente de que, dependiendo de la operación que queramos realizar, debemos usar uno u otro comando. Para paliar esto, se creó la orden apt a secas que reúne las operaciones más habituales. Introduciremos su uso más adelante.

packagekit

Gestor de paquetes que pretende dar una interfaz unificada a los gestores de paquetes de las distintas distribuciones. Está pensado fundamentalmente para proveer una API con la que los entornos de escritorio puedan construir aplicaciones gráficas de gestión de paquetes.

synaptic

Gestor de paquetes para el escritorio gnome.

2.6.2.3. Operaciones básicas

Antes de realizar cualquier operación sobre paquetes es importante cerciorarse de cómo se obtendrán. Lo habitual es que éstos se obtengan de internet, lo que exige tener definidos los repositorios en el fichero /etc/apt/sources.list. Un contenido típico es el siguiente:

# /etc/apt/sources.list

deb http://ftp.cica.es/debian/ stretch main contrib non-free
# deb-src http://ftp.cica.es/debian/ stretch main

deb http://security.debian.org/debian-security stretch/updates main
# deb-src http://security.debian.org/debian-security stretch/updates main

Cada línea del fichero representa una fuente de obtención de paquetes y su sintaxis es la siguiente:

deb|deb-src URL distribución componente1 [componente2 [componente3]]

En particular, el significado de cada campo es el siguiente.

  1. Las línea que empiezan por deb representan fuentes para paquetes compilados, mientras que las líneas que empiezan por deb-src, fuentes para paquetes de código fuente que necesitan compilarse. Por lo general, los paquetes compilados tienen un correspondiente sin compilar por si deseamos hacer esta operación nosotros mismos. No es lo habitual y, de hecho, en el ejemplo, están comentadas las líneas (anteponiendo en ellas una almohadilla) para que no tengan efecto.

  2. La URL indica la dirección del repositorio. Hay muchísimos repartidos por todo el mundo. La lista completa puede obtenerse de la página de debian.

  3. En el campo referente a la distribución puede incluirse o el nombre de la distribución (el personaje de Toy Story) o el nombre de la rama (oldstable, stable, testing, unstable, experimental, etc.)3

  4. El componente hace referencia a main, contrib o non-free. Lo habitual es tener main, que contiene el grueso de los paquetes, y de forma accesoria contrib y non-free.

Advertencia

Si se hizo una instalación a partir de un cdrom, es muy probable que el propio cdrom esté incluido como fuente. Es más que recomendable eliminar la línea (o comentarla) para evitar el tedio de soportar que el gestor nos pida el cdrom.

Además de este fichero, puedes crearse otros .list dentro de /etc/apt/sources.list.d con repositorios más específicos.

Advertencia

No es buena idea mezclar distintas ramas (testing, sid) en un mismo sistema a menos que se haga con cuidado, lo cual implica hacer uso del apt-pinning.

Cerciorados de que se dispone de un repositorio válido, la primera acción es bajar la lista de paquetes disponibles o actualizarla si ya se realizó antes la operación:

# apt-get update

Esta operación es recomendable hacerla siempre antes de instalar un paquete.

Advertencia

La acción anterior no actualiza el sistema, sólo la lista de paquetes disponibles.

Actualizada la lista, es posible instalar un paquete individual o actualizar los paquetes a su versión más reciente. Esta última acción tiene dos variables:

# apt-get upgrade

que hace una actualización no traumática, es decir, sólo realiza las actualizaciones que no implican un cambio significativo en la composición de nuestros paquetes instalados. Estos cambios significativos pueden deberse al hecho de que le mantenedor de una aplicación haya decidido restructurar los paquetes relacionados con ella, de manera que una actualización implique borrar paquetes. Como consecuencia, pueden quedar paquetes retenidos sin actualizar. La variante que provoca una actualización completa4 es:

# apt-get dist-upgrade

Si nuestra intención es instalar software, por ejemplo, el paquete pv:

# apt-get install pv

Para desinstalar existen dos posibilidades:

  1. Hacerlo de modo que no se eliminen los fichero de configuración:

    # apt-get remove pv
    
  2. Hacerlo sin que quede rastro de ellos:

    # apt-get purge pv
    

También es posible instalar y desinstalar en una misma acción añadiendo los signos + o - tras el nombre del paquete:

#. apt-get install vim+ vim-tiny-

Cuando un paquete se instala, es común que dependa de otros paquetes que no están instalados y, como consecuencia que el sistema, se vea obligado a instalar más de un paquete. En este caso, apt-get nos informará y nos pedirá que confirmemos la operación. Si deseamos responder sí automáticamente, basta con incluir la opción -y:

# apt-get install -y vim+ vim-tiny-

Del mismo modo, al desinstalar un paquete es posible que paquetes que se instalaron solamente para satisfacer las dependencias de éste, queden sin razón de ser en el sistema. Esto es conocido por el gestor porque cuando instala un paquete lo marca como instalado manualmente o instalado automáticamente.

Por último, apt-get install permite también instalar paquetes .deb descargados previamente5. En este caso, para que la herramienta distinga un archivo de un paquete de repositorio, es necesario que en al expresar el archivo se incluya un path absoluto o relativo:

# apt-get install /tmp/AutoFirma_1_6_5.deb
# apt-get install ./AutoFirma_1_6_5.deb

Cuando se hacen operaciones de borrado (remove) y purga (purge), pero también de actualización (upgrade) o, incluso, de instalación (install), puede ocurrir que resulten paquetes huérfanos, esto es, paquetes instalados automáticamente, pero que ya son no son necesarios puesto que ningún paquete que requiera de su presencia, está ya instalado. En este caso, existe un comando específico para eliminarlos (que se nos sugerirá cuando el sistema detecte su presencia):

# apt-get autoremove

Sin embargo, podemos ahorrarnos esta operación si incluímos la opción --autoremove en cualquira de las operaciones anteriormente referidas:

# apt-get --autoremove remove nginx

Cuando se instala (install) o se actualiza el sistema (upgrade, dist-upgrade), se van descargando los paquetes necesarios y almacenando dentro de /var/cache/apt/archives. Esa es la razón por la que si cancelamos la orden y la proseguimos después, seguirá la descarga en el punto en que quedó. El caso es que tras la instalación y configuración de los paquetes, estos no se borran, sino que siguen en el directorio ocupando espacio. Por ese motivo, es conveniente borrarlos mediante la orden:

# apt-get clean

Advertencia

Antes de instalar o actualizar es muy, muy conveniente actualizar la lista de paquetes, porque podemos tenerla obsoleta y que los paquetes existentes en el repositorio no sean los mismos que nuestro sistema cree. De hecho, si intentamos instalar un paquete y el sistema nos informa de que éste no existe, supuesto que tengamos bien la conexión a internet, la razón casi segura es que estamos trabajando con una lista obsoleta y haya que actualizarla.

Nota

Dado que que conveniente actualizar la lista antes de instalar es muy común escribir líneas como esta:

# apt-get update && apt-get install -y pv && apt-get clean

Para buscar paquetes adecuados para una determinada tarea son útiles dos comandos:

# apt-cache search términos de búsqueda

que nos devolverá los paquetes relacionados con los términos de búsqueda que se incluyan. Y cuando se duda si instalar un paquete o no, puede mirarse la descripción completa del mismo a través de:

# apt-cache show pv

2.6.2.4. apt como alternativa

Nota

A pesar de que las explicaciones se hayan basado en la familia de apt-get, por comodidad es preferible usar esta herramienta.

apt es una buena alternativa para las operaciones definidas bajo el epígrafe anterior: reducen a uno el comando y, además, ofrece un aspecto mejorado (colores, barra de progresión, etc.). Las equivalencias son las siguientes:

Familia apt-*

Orden apt

apt-get install

apt install

apt-get remove

apt remove

apt-get purge

apt purge

apt-get update

apt update

apt-get upgrade

apt upgrade

apt-get dist-upgrade

apt full-upgrade

apt-get autoremove

apt autoremove

apt-cache search

apt search

apt-cache show

apt show

dpkg -l

apt list

A las posibilidades ya descritas al tratar apt-get, se pueden hacer algunas precisiones:

apt list

Tiene algunas diferencias con dpkg -l:

  • Permite añadir, como dpkg, patrones para filtrar paquetes:

    $ apt list 'z*' 'h*'
    
  • Aunque devuelve todos los paquetes de la distribución, permite añadir una opción para afinar:

    • --installed sólo muestra paquetes instalados.

    • --upgradable sólo muestra los paquetes con versión más reciente en los repositorios.

    Por ejemplo:

    $ apt list --installed 'n*'
    

devuelve todos los paquetes instalados cuyo nombre empieza por «n».

apt remove, apt purge, apt upgrade, apt full-upgrade

Como su respectivo equivalente, disponen de la opción --autoremove para que junto al paquete que explícitamente se desea borrar, se borren también los paquetes que dependen exclusivamente de éste y que se instalaron automáticamente.

apt install

además de instalar los paquetes necesarios, borra de la caché los ficheros descargados, por lo que no es necesario, limpiarla luego con clean.

2.6.2.5. Otras operaciones

Bajo este epígrafe se enumerarán algunas otras operaciones relacionadas con los paquetes y la gestión de paquetes, pero que se realizan con menor frecuencia.

2.6.2.5.1. Acciones sobre paquetes

La más socorrida es comprobar si un paquete está instalado o no:

$ dpkg -l <paquete>

Puede sustituirse el nombre de paquete por una expresión como las que usa bash. Esto, por ejemplo, mostraría los paquetes cuyo nombre empieza por la letra p seguida de v o a6:

$ dpkg -l 'p[av]*'

Cuando un paquete está perfectamente instalado, la línea que lo describe debe comenzar por ii.

También es útil conocer cuáles son los ficheros que contiene un paquete:

$ dpkg -L <paquete>

y a qué paquete pertenece un determinado fichero. Por ejemplo, si quisiéramos saber qué paquete instala el comando cp:

$ dpkg -S $(which cp)

Nota

Obsérvese que se ha preferido incluir la ruta completa (/bin/cp) frente al nombre solo (cp). Esto es debido a que la búsqueda funciona de tal forma que se devuelve un paquete como resultado cuando contiene un fichero cuya ruta completa incluye el argumento. Por tanto, si hubiéramos hecho dkpg -S cp se habrían devuelto infinidad de resultados. Hágase la prueba.

Advertencia

Desde Buster esta consulta no funcionará en ocasiones, cuando el paquete haya instalado el ejecutable bajo /bin. Esto es debido a que a partir de esta versión /bin es un enlace simbólico a /usr/bin y, en consecuencia, which devolverá como ruta esta segunda localización. Es el caso del ejemplo sugerido.

dpkg puede también ser útil cuando instalamos a mano un paquete .deb descargado, por ejemplo, de una web que lo proporciona en este formato:

# dpkg -i paquete.deb

Cuando se obra así, muy comúnmente, tal paquete necesita de otros que no están aún instalados en el sistema. Como de resolver dependencias se encarga apt-get, pero no dpkg, el paquete quedará a medio instalar e inusable. Para resolverlo y que automáticamente se instalen las dependencias basta con hacer:

# apt-get -f install

Nota

En cualquier caso, es preferible la orden:

# apt-get install ./paquete.deb

que se encargará no sólo de instalar el paquete, sino de satisfacer sus dependencias.

2.6.2.5.2. Acciones sobre el sistema de paquetes

En ocasiones es conveniente saber cuáles son las dependencias de un paquete:

$ apt-cache depends pv
pv
  Depende: libc6
  Sugiere: doc-base

Y en otras qué paquetes dependen de él:

$ apt-cache rdepends pv
pv
Reverse Depends:
  btrbk
  xvidenc
  h264enc
  divxenc
  vzctl

Hay un aspecto de los paquetes interesante también que aún no se ha mencionado: las marcas, que operan en dos aspectos distintos:

  • Un paquete puede estar marcado como de instalación manual o automática. Lo primero quiere decir que el paquete fue explícitamente instalado, mientras que lo segundo que se instaló para resolver una dependencia. Tiene importancia, porque en el segundo caso, si se eliminan los paquetes de los que depende el marcado como automáticamente instalado, el sistema nos sugerirá que lo desinstantemos (con apt-get autoremove). Estas marcas las establece sin nuestra intervención el gestor de paquetes, pero nosotros podemos forzar que el paquete la cambie.

  • Un paquete puede estar marcado como retenido (hold). Si es así, no se actualizará ni se eliminará jamás.

Para manejar las marcas, disponemos del comando apt-mark:

  1. Marca como automáticamente el paquete pv:

    # apt-mark auto pv
    
  2. Marca como instalado manualmente el paquete pv:

    # apt-mark manual pv
    
  3. Muestra todos los paquetes instalados manualmente:

    $ apt-mark showmanual
    
  4. Muestra todos los paquetes instalados automáticamente:

    $ apt-mark showauto
    
  5. Marca el paquete pv como retenido:

    # apt-mark hold pv
    
  6. Desmarca el paquete pv como retenido:

    # apt-mark unhold pv
    
  7. Muestra los paquetes retenidos:

    # apt-mark showhold
    

Además, con apt-mark podemos saber los paquetes instalados (showinstall), eliminados (showremove) y purgados (showpurge).

2.6.2.5.3. Adición de repositorios extraoficiales

En ocasión nos encontramos con la necesidad de añadir repositorios extraoficiales que empaquetan alguna utilidad interesante. Por ejemplo, este que permite instalar un paquete para Google Earth:

# cat >> /etc/apt/sources.list.d/google.list
deb http://dl.google.com/linux/earth/deb/ stable main

El problema de ello es que los repositorios está firmados con GPG y al intentar actualizar las listas de paquetes es bastante probable que nuestro apt no disponga de la clave pública y no tenga confianza. En consecuencia, se malogrará la descarga de la lista de paquetes disponibles en el repositorio y nos quedaremos sin poder instalar los paquetes que proporciona:

# apt update
[...]
W: Error de GPG: http://dl.google.com/linux/earth/deb stable Release: Las firmas siguientes
no se pudieron verificar porque su clave pública no está disponible: NO_PUBKEY 1397BC53640DB551
E: El repositorio «http://dl.google.com/linux/earth/deb stable Release» no está firmado.
N: No se puede actualizar de un repositorio como este de forma segura y por tanto
está deshabilitado por omisión.
[...]

Para solucionarlo basta con importar la clave pública requerida a nuestro anillo personal de claves y, hecho esto, exportarla al anillo de apt. Use el identificador que proporciona el propio apt (en el ejemplo, 1397BC53640DB551):

# gpg --keyserver keys.gnupg.net --recv-key 1397BC53640DB551
# gpg -a --export 1397BC53640DB551 | apt-key add -

Ver también

Consulte cómo funciona el cifrado GPG.

2.6.2.5.4. Mezclando ramas y arquitecturas

Lo habitual es que nuestro sistema esté constituido por paquetes de una sola arquitectura (muy pòsiblemente, amd64) y una única rama (stable, testing, etc.). En ocasiones, sin embargo, necesitamos mezclar, lo cual es posible, pero exige ser bastante cuidadoso.

2.6.2.5.4.1. Mezcla de arquitecturas

Lo normal es disponer de un sistema con paquetes compilados para amd64, pero puede darse el caso de que necesitemos instalar un paquete que no es software libre y sólo está compilado para 32 bits (i386). Dado que son arquitecturas compatibles (un ejecutable de 32 bits se puede ejecutar en una plataforma de 64 bits), no hay ningún problema con el programa; el problema real es que este programa necesitara muy probablemente librerías de 32 bits que se encuentran en otros paquetes; y, aunuqe dispongamos de las correspondientes de 64 bits, no servirá.

Para conocer la arquitectura principal de nuestro sistema podemos ejecutar lo siguiente:

$ dpkg --print-architecture
amd64

Así que si quisiéramos añadir la arquitectura i386:

# dpkg --add-architecture I386

Para que el cambio tenga efecto, es necesario refrescar la lista de paquetes:

# apt-get update

De lo cual resulta:

$ dpkg --print-architecture
amd64
$ dpkg --print-foreign-architectures
i386

Es decir, tenemos un sistema cuya arquitectura principal es amd64, y que tiene como arquitectura adicional i386. Esto significa que cuando pidamos instalar o eliminar un paquete, se presupondrá que nos referimos a la arquitectura amd64 y que sólo en caso de que especifiquemos instalaremos (o eliminaremos) un paquete para arquitectura i386:

# apt-get install pv:i386

Si en algún momento quiere eliminarse la arquitectura adicional, se deben borrar todos los paquetes para tal arquitectura, antes de eliminarla:

# apt-get purge '.*:i386'
# dpkg --remove-architecture I386

2.6.2.5.4.2. Mezcla de ramas

Otra posibilidad de mezcla es la de mezclar distintas ramas. Debe haber una verdadera razón para ello y no dejarse a la ligera, porque puede traer problemas.

Antes de embarcarse en ello, es necesario conocer precisamente cuál es el criterio que sigue debian para instalar unos paquetes frente a otros:

$ man apt_preferences

Aquí expondremos de ello un pequeño resumen y algunas reglas útiles.

En principio, si en nuestro /etc/apt/sources.list sólo incluímos repositorios de una rama (que es lo habitual), obviamente, sólo se instalarán repositorios de tal rama, puesto que los únicos paquetes de los que tendrá conocimiento nuestro sistema serán sus paquetes. Ahora bien, ¿qué ocurre si nuestro sources.list es el siguiente?:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
### Distribución estable
deb http://ftp.cica.es/debian/ jessie main

# Acutalizaciones y seguridad
deb http://ftp.cica.es/debian/ jessie-updates main
deb http://security.debian.org/ jessie/updates main

### Backports
deb http://httpredir.debian.org/debian jessie-backports main

### Distribución en pruebas
# deb http://ftp.cica.es/debian/ stretch main

Como vemos, tenemos en el sistema la rama estable junto a sus actualizaciones, los backports y, además, la distribución de pruebas. Un batiburrillo, que hay que saber gestionar.

Para pronosticar qué ocurre, es necesario saber primero que todos los paquetes llevan asociada una prioridad, que se calcula según las siguientes reglas:

Prioridades predefinidas

Prioridad

Paquetes

1

Ramas7 con la opción NotAutomatic: yes8, pero sin la opción ButAutomaticUpgrades: yes.

100

Paquetes instalados.

Ramas9 con las opciones NotAutomatic: yes y ButAutomaticUpgrades: yes.

500

Ramas que no sean las anteriores ni la rama objetivo. Lo habitual es la rama objetivo no esté definida.

990

Rama objetivo.

Y las reglas para decidir si un paquete se instala o no son estas:

  1. Se instala el paquete con mayor prioridad, aunque para que se instale un paquete de una versión más reciente a la instalada, se exige además que tenga una prioridad de al menos 1000.

  2. Si coinciden las prioridades, se instala el paquete más reciente.

Sabido esto, podemos volver a la nuestro sources.list de ejemplo. Resulta que en él todas las ramas tienen prioridad 500, excepto la de backports que tiene prioridad 100. Consecuentemente, cada vez que intentemos instalar un paquete, se evitará la rama backports y se instalará aquel más reciente, que se encontrarán normalmente en las ramas de actualización y seguridad.

¿Cómo podemos entonces instalar un paquete de backports? Muy sencillo: basta con hacer tal rama, la rama objetivo para esa instalación. Eso se hace añadiendo la opción -t a la orden:

# apt-get install -t jessie-backports nginx

Advertencia

Este comando no implica sólo instalar el paquete nginx de backports, sino él y todas sus dependencias. Si entre sus dependencias hay librerías, incluso las más básicas, entonces se instalarán (o actualizarán) también. Por lo general, backports está pensada para que haya versiones más recientes de software, pero que estas versiones se hayan compilado con las mismas librerías básicas que usa la estable. Por tanto, al realizar esta operación, sólo actualizaremos los paquetes más intimamente ligados con la aplicación que queremos actualizar. Pero esto no es aplicable a la rama testing ni a la inestable.

El fichero, tal y como está, guarda bastante equilibrio: instalaremos paquetes de la estable, convenientemente actualizada con paquetes de seguridad, y sólo si explícitamente pedimos la actualización de un paquete que haya en backports se llevará a cabo. Ahora bien, ¿qué ocurre si descomentamos la línea referente a la rama en pruebas? Que el equilibrió se romperá: los paquetes de la rama en pruebas también tienen prioridad 500, pero en su mayoría serán versiones más recientes y que, además, están en constante actualización. La consecuencia será que si actualizamos todo el sistema, pasaremos de tener la rama estable a tener la rama en pruebas y que todos los paquetes que instalemos serán de esta última versión. Es decir, que el resto de líneas de sources.list sobrarán por completo.

Para tener mayor control, apt permite alterar las prioridades predefinidas. Esto se hace modificando (o creando el fichero /etc/apt/preferences10), dentro del cual se incluyen estructuras del siguiente tipo separadas por una línea en blanco:

Package: <expr_paquete>
Pin: <selector>
Pin-Priority: <N>

es decir, en cada estructura definimos una expresión que escoge los paquetes para los que se hace la definición, un selector que indica para qué ejemplares del paquete (versión, rama a la que pertenece, etc.) y, por último, la prioridad que le pensamos otorgar.

Línea Package

Para expresar el paquete hay varias posibilidades. Las dos más simples son indicar el nombre exacto del paquete o escribir un *, que (como es lo habitual) significa cualquier paquete. Las otras dos son:

  • Espresiones glob, esto es, las expresiones que se usan en bash. Por ejemplo, python3-* haría referencia a todos los paquetes que comienza por python3-.

  • Expresiones regulares que deben delimitarse entre barras. POr ejemplo, /py/ refiere todos los paquetes que contengan la subcadena py.

Línea Pin

La selección del ejemplar del paquete la determina el contenido del campo Pin. Hay diferentes criterios para realizar esta selección:

  • La versión del propio paquete:

    Pin: version 1.10*
    

    En este caso, no se especifica una versión concreta exacta, sino cualquier version que empiece por 1.10.

  • El origen del paquete, esto es, de dónde se descarga:

    Pin: origin "ftp.cica.es"
    

    Si se usa una cadena vacía (origin ""), el paquete se descarga de un sitio local.

  • Las propiedades de la distribución a la que pertenece el paquete. Son diversas y se pueden consultar el los ficheros *Release, citados en una de las notas al pie. Se enumeran aquí algunas propiedades, expresando el nombre del campo con que se enuncian en tal fichero:

    • La rama con su nombre genérico*stable*, testing, etc. (Suite):

      Pin: release a=testing
      
    • La rama con su nombre clave (Codename):

      Pin: release n=stretch
      
    • La versión de la distribución (Version):

      Pin: release v=8
      

      En este caso, la versión 8. Sólo es válido para la rama estable, porque sólo esta tiene asignado un número de versión.

    • El componente:

      Pin: release c=main
      
    • La distribución (debian, ubuntu) relacionada con dos etiquetas Label:

      Rin: release l=Ubuntu
      

      y Origin:

      Rin: release o=Origin
      
Línea Pin-Priority:

Símplemente hay que indicar la prioridad numérica. Para fijar una adecuada, conviene tener en cuenta que, de acuerdo con las prioridades predeterminadas, el comportamiento de un paquete ante la instalación o la actualización será el siguiente (P es su prioridad):

P>=1000:

El paquete se instala en cualquier caso, incluso aunque haya una versión instalada más reciente.

990<=P<1000:

El paquete se instala por encima incluso de los provenientes de la rama objetivo. No lo hará unicamente si hay una versión más reciente instalada.

500<=P<990:

El paquete se instala a menos que la versión instalada sea más reciente o haya un ejemplar disponible en la rama objetivo.

100<=P<500:

Sólo se instala el paquete si no hay otro ejemplar disponible en alguna rama y es más reciente que el instalado.

0<P<100:

Sólo se instala si no hay ninguna versión disponible ni instalada.

P<0:

El paquete no se instalará jamás.

Teniendo en cuenta todo esto, una posibilidad para conciliar tener a la vez como fuente testing y stable sería esta:

Package: *
Pin: release a=testing
Pin-Priority: 99

De este modo, al hacer:

# apt-get install paquete

Sólo se instalaría un paquete de la rama en pruebas si no estuviera disponible en la rama estable. Eso sí, si necesitara versiones de librerías posteriores a las que se encuentran en la estable, no se llegaría a instalar, porque no se podría satisfacer sus dependencias. Si en este caso hiciéramos:

# apt-get install -t testing paquete

Esto sí se instalaría a costa de instalar también versiones en pruebas de ciertas librerías. Esto, sin embargo, no es recomendable, porque pueda dar pie a problemas. En este caso, sería más recomendable descargar el paquete fuente de testing e intentar compilarlo con las librerías de la estable.

Por último, cuando se mezclan distintas ramas es conveniente saber para un paquete qué versión proporciona cada una de ellas. Para ello es muy útil el comando apt-show-versions disponible en el paquete del mismo nombre (no viene instalado por defecto):

$ apt-show-versions -a -p pv
pv:amd64 1.5.7-2 install ok installed
pv:amd64 1.5.7-2 stable  ftp.cica.es
No stable-updates version
pv:amd64 1.6.0-1 testing ftp.cica.es
pv:amd64/stable 1.5.7-2 uptodate

Se ha ejecutado la orden en un sistema que se provee de la estable y testing y con las preferencias ajustadas tal y como se ha indicado (los paquetes de testing tiene prioridad 99). En estas condiciones la orden nos informa de que tenemos intalada la versión 1.5.7, que es justamente, la de la versión estable; que hay otra versión más moderna (1.6.0) en testing, pero que estamos actualizados (uptodate). Y lo estamos justamente por el hecho de haber definido la prioridad.

2.6.2.6. Compilación de paquetes

Aunque no es algo habitual y además resulta engorroso de mantener11, es bastante sencillo compilar una código fuente para obtener los paquetes compilados. Lo primero es añadir a /etc/apt/sources.list la línea que nos permite acceder a los paquetes de las fuentes. Por ejemplo:

deb-src http://ftp.cica.es/debian/ stretch main

Y, hecho esto, se deberá actualizar la lista de paquetes:

# apt-get update

y añadir las herramientas para compilar:

# apt-get install build-essential

Con todo esto la compilación es muy sencilla. Requiere descargar los paquetes que exige la compìlación del que pretendemos compilar12 (supongamos que pv):

# apt-get build-dep pv

y descargar el paquete con el código fuente:

# cd /usr/src
# apt-get source pv

E ir al directorio donde se almacena y compilar:

# cd pv-1.6.0
# dpkg-buildpackage -us -uc

Si la compilación acaba sin problemas, el paquete .deb estará en el directorio superior y bastará con instalarlo:

# cd ..
# dpg -i pv_1.6.0-1_amd64.deb

Nota

Puede ocurrir que la compilación del paquete genere varios paquetes compilados.

Nota

El directorio /usr/src quedará lleno de ficheros relacionados con la compilación y el código fuente que pueden borrarse cuando acaba el proceso.

No relacionado con la compilación, pero sí con la obtención de un paquete .deb es el caso en que queremos reconstruir el paquete a partir de los ficheros que tenemos instalados en el disco duro, bien porque no encontramos cómo hacernos con el .deb original, bien porque hemos cambiado sus ficheros de configuración y queremos empaquetarlo en el estado en el que está en nuestro sistema para trasladarlo a otro. En ese caso es muy útil la orden dpkg-repack que hay que instalar primero:

# apt-get install dpkg-repack
# dpkg-repack pv

2.6.2.7. Destripando paquetes

Los ficheros .deb son empaquetados comprimidos de ficheros que, además de poder instalarse, pudeden descomprimirse y desempaquetarse a fin de poder acceder a su interior. Para lograr esto, es conveniente instalar

fakeroot

Simula que el usuario es el administrador dentro de un entorno en el que se manipulan ficheros.

Para acceder al contenido de un .deb, lo primero es conseguir uno. Consigámoslo, descargando el fichero con apt-get, pero sin llegar a instalarlo:

# apt-get install -d pv

La orden habrá almacenado el fichero descargado en /var/cache/apt/archives. Podemos analizar el contenido de este fichero haciendo uso del comando:ar:

$ ar t /var/cache/apt/archives/pv_*.deb
debian-binary
control.tar.gz
data.tar.xz

Contiene tres ficheros, el primero guarda simplemente la versión del formato .deb y los otros dos son archivos empaquetados y comprimidos, uno (data.tar.xz) guarda los ficheros en sí que constituyen el paquete y el otro (control.tar.gz) los ficheros de metainformación, es decir, los ficheros que sirven para identificar cuál es el paquete, qué ficheros debe contener o qué acciones hay que realizar cuando se instala o se elimina el paquete del sistema. No entraremos a describir cuáles son estos ficheros control, pero puede leerse información al respecto aquí).

No obstante, no segujiremos por este camino, puesto que el propio dpkg tiene las herramientas necesarias para desempaquetar el fichero:

$ cd /tmp
$ mkdir CACA
$ dpkg -x /var/cache/apt/archives/pv_*.deb CACA
$ dpkg -e /var/cache/apt/archives/pv_*.deb CACA/DEBIAN

Usamos como directorio para almacenar el contenido /tmp/CACA. La primera operación descomprime los ficheros en sí dentro de tal directorio, de manera que estos forman la misma estructura que tienen cuando se instalan en el sistema, mientras que la segunda almacena dentro de un subdirectorio llamado DEBIAN los ficheros de metainformación. En este punto podríamos realizar modificaciones de tanto de los ficheros de datos como de los de control (¡ojo! que el fichero de control md5sums almacena las comprobaciones de la integridad de los ficheros).

Si en algún momnento quisiéramos reconstruir el fichero, podríamos hacer lo siguiente:

$ cd /tmp/CACA
$ dpkg-deb -b . ../pv_1.5.7-2_amd64.deb

Nota

En realidad, conociendo cuáles son los ficheros de control y cómo se escriben, es posible crear nuestros propios ficheros .deb. Basta con reproducir la estructura que hemos visto al descomprimir el fichero y empaquetar todo con dpkg-deb.

2.6.2.8. Ejercicios sobre gestión de software

  1. Actualizar el sistema:

    1. Sin más.

    2. Eliminando también los paquetes que se vuelven innecesarios.

  2. Instalar las herramientas para soportar NTFS.

  3. Instalar la versión ligera del servidor web nginx.

  4. En la misma orden desinstalar la versión anterior e instalar la versión completa.

  5. Averiguar a qué paquete pertenece el ejecutable nginx.

  6. Comprobar si tenemos instalado, el paquete gcc.

  7. Consultar para qué sirve el paquete vlan.

  8. Buscar algún paquete que nos permita jugar al Pacman (pero para consola de texto, porque no tenemos entorno gráfico)

  9. Desinstalar el juego anterior.

  10. Hacer una actualización completa del sistema.

Notas al pie

1

Existen otros farmatos de ficheros y, en general, cada distribución madre tiene su propio formato: Red Hat (y SuSE) usa ficheros .rpm, Archinux, ficheros .pkg.tar.xz; Gentoo, paquetes ebuild; y Slackware, .tgz.

2

En realidad, la tradición se debe a que el segundo líder del proyecto debian, Bruce Perens, participó en la realización de la película Toy Story 2 e inició la costumbre a partir de la versión 1.1, a la que llamó Buzz.

3

La diferencia entre tener los nombres clave o los nombres de la rama está exclusivamente en el momento en que se produzca un cambio de versión. Si, por ejemplo, colocamos hoy el nombre de la actual distribución en pruebas (stretch), tendremos instalada en nuestra máquina la distribuciín en pruebas, pero después de que esta se congele y pase a ser la distribución estable, pasaremos a tener instalada la estable. En cambio, si lo que colocamos es la palabra testing, al abrirse de nuevo la distribución en pruebas a las actualizaciones de sid nuestro sistema se actualizará y continuaremos, como en un principio, teniendo instalada la distribución en pruebas.

4

En la distribución estable, al ser las actualizaciones sólo de seguridad o de corrección de errores, no se producen casos de paquetes retenidos.

5

O sea, paquetes que no se encuentren en los repositorios, sino que los hayamos descargado manualmente de la web. Por ejemplo, el programa autofirma que ofrece para descarga el Gobierno de España.

6

Acuérdese de proteger la expresión para no correr el riesgo de que la pueda interpretrar el propio :program:` bash`.

7

Es el caso de la rama experimental.

8

Para saber cuáles son las opciones que tiene fijadas una rama se puede ir al directorio /var/lib/apt/lists dentro del cual encontraremos los ficheros descargados por la orden apt-get update. Cada línea del sources.list genera varios ficheros uno de los cuales tiene por nombre *Release. Dentro se podrá ver cuáles son las opciones de la rama.

9

Es el caso de la rama backports.

10

Como es habitual, también existe un directorio llamado /etc/apt/preferences.d en el que podemos crear diferentes ficheros para hacer más modular la configuración.

11

Engorroso, porque para que una nueva versión del paquete no machacara nuestra compilación, deberíamos marcar como hold el paquete y luego ir periódicamente repitiendo la compilación según salgan nuevas fuentes. Tiene algo más de sentido, si compilamos un paquete de una rama con versiones más modernas (testing, si tenemos stable; o sid, si testing), porque podremos compilar el paquete nuevo y, después, esperar sin miedo a que nuestra rama alcance esa versión. Cuando la supere, se machacará nuestra compilación, pero con una versión más moderna.

12

Los paquetes que se instalan mediante este procedimiento se marcan como instalados manualmente, cuando es más conveniente que se marcaran como instalados automáticamente para que después de la compilación, se borraran, puesto que no se necesitan más. Para solucionarlo, se puede anterar la confiruación de apt del siguiente modo:

# echo 'APT::Get::Build-Dep-Automatic "true";' > /etc/apt/apt,conf.d/99buildep