Lanzas por SSH un script de instalación largo en un servidor Ubuntu 24.04 (Docker, swap, dependencias). A mitad de camino se corta la conexión, vuelves a entrar, ejecutas de nuevo el script y falla al primer apt-get:
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (apt-get)
N: Be aware that removing the lock file is not a solution and may break your system.
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
El mensaje no habla de un fallo: dice que otro proceso tiene el candado del gestor de paquetes. Este artículo explica cómo averiguar cuál es, qué hacer con él sin dañar el sistema y cómo lanzar trabajos largos para que no dependan de tu terminal. Los comandos se contrastaron con los manuales de apt, dpkg y systemd, y con la documentación de Ubuntu Server; no se ejecutaron sobre un servidor.
Por qué pasa
El gestor de paquetes permite que un solo proceso modifique la base de datos de paquetes a la vez, y lo garantiza con archivos de bloqueo como /var/lib/dpkg/lock-frontend. Cuando el candado está en uso, el segundo proceso se niega a continuar e indica el PID y el nombre del que lo tiene (aquí, apt-get).
Si la sesión SSH se corta a mitad de una instalación, desaparece el terminal, pero eso no garantiza que terminen todos los procesos que lanzó el script. Un apt-get o un dpkg que ya estaba en marcha puede seguir trabajando sin que nadie lo mire, y mientras lo haga conserva el candado. Es la razón por la que el segundo intento falla: el primero todavía no terminó.
También puede ser otro proceso del sistema. La documentación de Ubuntu Server explica que unattended-upgrades puede ejecutarse al arrancar la máquina y, mientras trabaja, impide otras operaciones de paquetes: si necesitas instalar algo, debe esperar a que terminen las actualizaciones. Es frecuente en un servidor recién creado.
La advertencia del propio mensaje lo resume: borrar el archivo de bloqueo no es la solución y puede dañar el sistema.
Solución
-
Identifica el proceso que tiene el candado. El mensaje ya da el PID. Con él y con las herramientas del sistema:
ps -p 1234 -o pid,etime,cmd sudo fuser -v /var/lib/dpkg/lock-frontend sudo lsof /var/lib/dpkg/lock-frontend ps -ef | grep -E 'apt|dpkg'ps -pmuestra el comando completo y el tiempo que lleva en marcha (etime).fuser -vlista los procesos que usan el archivo, en formato parecido aps;lsofhace algo equivalente, usa el que tengas instalado. La última línea busca cualquier proceso de apt o dpkg (verás también la propia línea degrep). -
Comprueba si avanza. Mira el registro de dpkg y el registro de tu script:
sudo tail -f /var/log/dpkg.log tail -f instalar.logSi aparecen líneas nuevas (paquetes que se descomprimen, se configuran), el proceso sigue trabajando.
-
Si avanza, espera a que termine. Este bucle se detiene cuando nadie usa el archivo (
fuserdevuelve un código distinto de cero si ningún proceso accede a él):while sudo fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do sleep 5; done; echo "candado libre"Después vuelve a lanzar el script. Antes, comprueba que se pueda repetir sin efectos secundarios: instalar un paquete ya instalado no cambia nada, pero crear un archivo de swap o agregar una línea a
/etc/fstabpor segunda vez sí puede. -
Si lleva mucho tiempo sin avanzar, deténlo con cuidado. Pide primero una terminación normal y espera:
sudo kill 1234Evita la señal
SIGKILL(kill -9) salvo como último recurso: puede dejar paquetes a medio instalar. Si el proceso se interrumpió, repara el estado de dpkg antes de seguir:sudo dpkg --configure -a sudo apt-get install -fSegún el manual de dpkg,
--configure -aconfigura todos los paquetes desempaquetados pero sin configurar. La opción-f(--fix-broken) de apt-get intenta corregir un sistema con dependencias rotas. -
No borres los archivos de bloqueo (
rm /var/lib/dpkg/lock-frontendy similares). El mensaje de apt lo desaconseja de forma explícita, y el candado lo tiene un proceso vivo, no el archivo. -
Lanza los trabajos largos desacoplados de tu terminal. Tres opciones, de menos a más robusta:
# 1. En una sesión nueva, sin terminal asociado sudo setsid -f bash ./instalar.sh > instalar.log 2>&1 < /dev/null tail -f instalar.log # 2. Dentro de tmux: puedes desconectarte y volver tmux new -s instalacion bash ./instalar.sh # Ctrl+b d para desacoplar; después: tmux attach -t instalacion # 3. Como servicio transitorio de systemd sudo systemd-run --unit=instalacion /bin/bash /ruta/instalar.sh journalctl -u instalacion -fEl manual de
setsidindica que ejecuta un programa en una sesión nueva (y-fobliga a crear un proceso nuevo, de modo que el comando devuelve el control enseguida). Lanza el script consudodesde el principio: sin terminal no podrás responder a una petición de contraseña a mitad del trabajo. Entmux,new -screa una sesión con nombre yattach -tse conecta a ella; la tecla para desacoplar por defecto esCtrl+bseguida ded. Consystemd-run, el comando corre como un servicio gestionado por systemd, en un entorno limpio y separado, con el gestor de servicios como proceso padre. -
Si el trabajo debe sobrevivir a un reinicio, crea un servicio. Archivo
/etc/systemd/system/instalacion.service:[Unit] Description=Instalacion inicial del servidor Wants=network-online.target After=network-online.target [Service] Type=oneshot ExecStart=/bin/bash /opt/instalador/instalar.sh RemainAfterExit=yes Restart=on-failure RestartSec=30 [Install] WantedBy=multi-user.targetsudo systemctl daemon-reload sudo systemctl enable instalacion.service sudo systemctl start --no-block instalacion.serviceEn
Type=oneshot, el tiempo de espera de arranque está desactivado por defecto, así que una instalación larga no se corta por duración.Restart=on-failureestá permitido para este tipo (el manual rechazaalwaysyon-success) y relanza el script si termina con error, por lo que el script debe poder repetirse sin efectos secundarios.RemainAfterExit=yesmantiene el servicio como activo cuando el script termina bien.enablelo habilita para los próximos arranques. Sin--no-block,systemctl startespera a que el arranque de la unidad se complete, y en un serviciooneshoteso ocurre cuando el script termina; con la opción, solo encola el trabajo y te devuelve la consola.
Cómo verificar que quedó resuelto
sudo fuser -v /var/lib/dpkg/lock-frontend
echo $?
sudo dpkg --audit
Si nadie usa el archivo, fuser no imprime procesos y el código de salida es distinto de cero. dpkg --audit busca paquetes instalados solo en parte o con datos de control dañados; no debe listar nada. Si lanzaste el trabajo con setsid, tmux o systemd-run, cierra la sesión SSH, vuelve a entrar y comprueba que el registro (instalar.log o journalctl -u instalacion) sigue creciendo.
Variantes y errores relacionados
Otros archivos de bloqueo
El mismo error puede nombrar /var/lib/dpkg/lock o /var/lib/apt/lists/lock. El procedimiento es idéntico: el mensaje indica el proceso que lo tiene.
Lo tiene unattended-upgrades
Si el proceso es de actualizaciones automáticas, lo correcto es esperar. Según la documentación de Ubuntu, esas actualizaciones las lanzan los temporizadores apt-daily.timer y apt-daily-upgrade.timer, y sus registros están en /var/log/unattended-upgrades.
apt pide ejecutar dpkg --configure -a
Suele indicar que una instalación anterior se interrumpió. Ejecuta el comando como se indica en el paso 4 y repite después la instalación.
Dos instaladores a la vez
Si lanzaste el trabajo como servicio y además a mano, el segundo chocará con el candado del primero. Elige un solo mecanismo y revisa con systemctl status instalacion si ya está en marcha.
Resumen
- El error significa que un proceso vivo (por ejemplo, el
apt-getde la primera ejecución) tiene el candado de dpkg; no es un archivo corrupto. - Identifícalo con el PID del mensaje,
psyfuser -v; si avanza, espera; si está atascado, termínalo conkilly ejecutasudo dpkg --configure -a. - No borres los archivos de bloqueo: el propio apt advierte que puede dañar el sistema.
- Lanza instalaciones largas con
setsid -f,tmuxosystemd-run, con el registro en un archivo. - Si debe sobrevivir a reinicios, usa un servicio
Type=oneshotconRestart=on-failurey un script que se pueda repetir.
Comentarios
Publicar un comentario