Guía completa de lsof en Linux: consejos prácticos clave desde conflictos de puertos hasta liberación de espacio de archivos eliminados

Descripción general

Problemas como el ‘conflicto de puertos’ o ’el espacio en disco que no disminuye a pesar de haber eliminado archivos’, comunes durante la administración de sistemas Linux, se pueden resolver de inmediato con el comando lsof. En este artículo, analizaremos las técnicas esenciales para aplicar lsof directamente en entornos de producción dentro del ecosistema Linux, donde todo se gestiona como un archivo. Conozca paso a paso el conocimiento indispensable de resolución de problemas para ingenieros de sistemas, desde el rastreo de puertos hasta la liberación de bloqueos de archivos.

Comprobación básica de lsof e inspección de archivos abiertos por usuarios o procesos específicos

Para comprobar si el comando lsof está instalado en el sistema y, si no lo está, instalar el paquete correspondiente, ejecute el comando command -v lsof >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y lsof).

command -v lsof >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y lsof)

Para consultar la versión instalada y los detalles de compilación del comando lsof, ejecute el comando lsof -v.
⚙️ [Opciones principales]

-u : Consulta la lista de archivos y procesos abiertos por una cuenta de usuario específica.
-c : Filtra la lista de archivos abiertos por procesos cuyo nombre comienza con la cadena especificada.
-p : Examina la lista de archivos abiertos por un ID de proceso (PID) en particular.
-i : Consulta los procesos que utilizan sockets de red y puertos específicos.
+D : Busca de forma recursiva la lista de archivos abiertos en el directorio indicado y sus subdirectorios.
-t : Muestra de forma concisa únicamente los IDs de proceso (PID), uno por línea, lo cual resulta útil para scripts.

lsof -v

Para preparar un directorio de pruebas y un archivo de muestra para practicar con lsof, ejecute el comando mkdir -p /tmp/lsof_lab && echo '테스트 파일 내용' > /tmp/lsof_lab/sample.txt.

mkdir -p /tmp/lsof_lab && echo ‘테스트 파일 내용’ > /tmp/lsof_lab/sample.txt

Para rastrear en segundo plano el archivo de muestra creado y mantenerlo abierto mediante un proceso, ejecute el comando tail -f /tmp/lsof_lab/sample.txt &.

tail -f /tmp/lsof_lab/sample.txt &

El comando lsof -u $(whoami) | head -n 15 muestra hasta las primeras 15 líneas de la lista de archivos ocupados por los procesos ejecutados por el usuario actual que inició sesión.
Esto permite examinar información detallada sobre los archivos abiertos por la cuenta actual, incluidas librerías del sistema y ejecutables básicos.

lsof -u $(whoami) | head -n 15

El comando lsof -c tail busca y muestra la lista de archivos y librerías abiertos por procesos cuyo nombre es tail.
A través de esto, es posible verificar qué descriptores de archivo y librerías compartidas está referenciando el comando tail ejecutado en segundo plano.

lsof -c tail

Una vez finalizada la práctica, ejecute el comando killall tail 2>/dev/null || true para terminar de forma segura y limpiar el proceso tail que se ejecutaba en segundo plano.

killall tail 2>/dev/null || true

Comprobación de puertos de red y resolución de conflictos de procesos

Para preparar el entorno de práctica para la inspección de puertos y conflictos de procesos, verifique si python3 está instalado en el sistema y, si no es así, instale el paquete.

command -v python3 >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y python3)

Para probar la ocupación de puertos de red, inicie un servidor web básico en segundo plano en el puerto 8080.

python3 -m http.server 8080 >/dev/null 2>&1 &

Espere 1 segundo hasta que el proceso del servidor web iniciado en segundo plano se enlace correctamente al puerto 8080.

sleep 1

El comando lsof -i :8080 consulta los procesos que están utilizando el puerto 8080.
En la salida se puede confirmar que el proceso python3 con el PID 371 está en estado de escucha (LISTEN) en el puerto 8080.

lsof -i :8080

El comando lsof -i -P -n | head -n 15 muestra rápidamente la lista de sockets de red del sistema en formato numérico, sin convertir números de puerto ni direcciones IP a nombres.
Al omitir la resolución inversa de DNS y la asignación de nombres de servicios a puertos, permite identificar el estado de ocupación de puertos con rapidez y sin demoras.

lsof -i -P -n | head -n 15

El comando lsof -i TCP:8080 -sTCP:LISTEN filtra y muestra con precisión únicamente las conexiones del protocolo TCP en estado LISTEN dentro del puerto 8080.
Esto resulta útil para omitir conexiones de sesión innecesarias e identificar exactamente el proceso demonio que realmente está a la espera de conexiones en dicho puerto.

lsof -i TCP:8080 -sTCP:LISTEN

Al finalizar la práctica, termine de forma forzada el proceso del servidor web en segundo plano que ocupaba el puerto TCP 8080 para liberar los recursos asignados.

fuser -k 8080/tcp 2>/dev/null || kill $(lsof -t -i :8080) 2>/dev/null || true

Rastreo de directorios específicos y archivos que impiden el desmontaje (Device Busy)

Para reproducir una situación de bloqueo de directorio y prevención de desmontaje, cree un directorio para la práctica y desplácese a esa ruta.

mkdir -p /tmp/mount_test && cd /tmp/mount_test

Para crear el archivo de registro de destino que será abierto por el proceso, ejecute el comando echo '작업 중인 파일' > active_work.log.

echo ‘작업 중인 파일’ > active_work.log

Inicie un proceso sleep en segundo plano que tome el archivo creado como entrada estándar para mantenerlo ocupado continuamente.

sleep 30 < active_work.log &

Para comprobar el estado desde fuera del directorio ocupado, cambie la ruta de trabajo al directorio de inicio.

cd /root || cd ~

El comando lsof +D /tmp/mount_test rastrea y muestra de forma recursiva todos los archivos y procesos abiertos dentro del directorio indicado y sus rutas secundarias.
La salida confirma que el proceso sleep con el PID 450 tiene ese directorio como su directorio de trabajo actual (cwd) y mantiene abierto el archivo active_work.log en modo de lectura (0r), siendo la causa que impide el desmontaje.

lsof +D /tmp/mount_test

Una vez completada la práctica, termine de forma segura el proceso sleep en segundo plano que retenía el directorio y el archivo.

killall sleep 2>/dev/null || true

Elimine el directorio temporal de prueba y sus archivos secundarios utilizados durante la práctica para limpiar los recursos del sistema.

rm -rf /tmp/mount_test

Recuperación y limpieza de archivos fantasma (deleted) que ocupan espacio en disco

Para probar fugas de espacio en disco, cree un directorio de práctica y genere un archivo de prueba de gran tamaño de 10 MB.

mkdir -p /tmp/leak_test && dd if=/dev/zero of=/tmp/leak_test/large.img bs=1M count=10 >/dev/null 2>&1

Rastree el archivo grande creado en segundo plano para que un proceso mantenga activo su descriptor.

tail -f /tmp/leak_test/large.img &

Elimine forzadamente el archivo grande en uso a nivel del sistema de archivos para simular una fuga por archivo fantasma.

rm -f /tmp/leak_test/large.img

El comando lsof | grep '(deleted)' | head -n 5' consulta la lista de archivos que han sido eliminados del sistema de archivos pero que siguen abiertos por un proceso y, por lo tanto, continúan ocupando espacio en disco.
Con esto se pueden rastrear rápidamente los archivos fantasma y los procesos correspondientes cuyo espacio en disco no se libera a pesar de haber sido borrados con el comando rm.

lsof | grep ‘(deleted)’ | head -n 5

A partir del ID de proceso obtenido con lsof -t, inspeccione la lista de descriptores de archivo en el directorio /proc/$TARGET_PID/fd/.
Al verificar directamente los números de descriptor de archivo referenciados por el proceso, es posible vaciar el espacio ocupado sin reiniciar el proceso o, si es necesario, recuperar los datos originales eliminados a través de dicho descriptor.

TARGET_PID=$(lsof -t /tmp/leak_test/large.img 2>/dev/null | head -n 1) && [ -n “$TARGET_PID” ] && ls -l /proc/$TARGET_PID/fd/ || true

Al concluir la práctica, termine de forma segura el proceso en segundo plano que seguía reteniendo el archivo fantasma para liberar por completo el espacio en disco.

killall tail 2>/dev/null || true

Elimine por completo el directorio temporal utilizado en la práctica para limpiar los recursos del sistema.

rm -rf /tmp/leak_test

Hasta aquí hemos revisado de forma concisa los consejos prácticos clave sobre cómo aprovechar el comando lsof, desde resolver conflictos de puertos hasta recuperar espacio en disco ocupado por archivos eliminados.
Esperamos que los temas tratados en esta guía sean de gran utilidad para resolver incidencias durante la operación y resolución de problemas en servidores reales.