Cómo usar lsof en Linux (con un ejemplo práctico)

Contenidos

Cómo usar lsof en Linux con un ejemplo práctico

¿Alguna vez se preguntó cómo descubrir qué archivos están hoy en día abiertos y en uso en su sistema? El comando lsof de Linux enumera los archivos abiertos y proporciona mucha información adicional. Aprenda a utilizar lsof con estos ejemplos prácticos.

Que es lsof?

Disponible de forma nativa en cualquier sistema operativo Linux, el lsof El comando proporciona una lista de archivos abiertos. A pesar de esto, la salida puede ser un poco críptica y larga, especialmente cuando se usan muchas aplicaciones en un sistema determinado. Echemos un vistazo a lo básico lsof producción. Nosotros correríamos lsof como root.

Para iniciar sesión como root, puede abrir una ventana de terminal y escribir un comando como sudo su o su para recibir un mensaje de autenticación de root. Alternativamente, puede ejecutar sudo lsof. Tenga en cuenta que aunque puede correr lsof como usuario normal no root además, puede hallar que la salida está incompleta.

Ejemplo: básico lsof Producción

sudo su
lsof | head -n10

Inicio de la salida lsof y los nombres de las columnas lsof en una terminal Bash

Aquí empezamos el lsof herramienta usando el lsof comando, y capturó las primeras diez líneas de la salida usando una tubería (|) para enviar la salida de información por lsof a una secundaria head -n10 comando que captura solo las diez líneas superiores (encabezadas).

los lsof El comando enumera varias columnas. Primero vemos el MANDO columna que enumera el binario que contiene el archivo abierto / bloqueo de archivo abierto. A continuación, vemos la columna de identificación del procedimiento. PID que es extremadamente útil cuando se trata de depurar varios problemas de aplicaciones, incluidos los bloqueos de archivos retenidos incorrectamente. En la próxima sección veremos un ejemplo de cómo podemos utilizar lsof en combinación con kill para terminar (destructivamente) aplicaciones que disponen bloqueos de archivos incorrectos.

Si es compatible con su sistema operativo, el TID La columna puede ayudar a darse cuenta de si una línea determinada es un procedimiento o una tarea. Si la salida está en blanco, como se puede ver en nuestro ejemplo (que se ejecuta en Linux Mint, un sistema operativo que admite el TID salida de columna), la línea / comando dado es un procedimiento, una no tarea. Si, a modo de ejemplo, inicia una aplicación de calculadora en su sistema operativo, dicho de otra forma, una tarea, esta columna se completará con un número de identificación de tarea / hilo.

los TASKCMD La columna contiene el nombre del comando de la tarea. Nuevamente, solo es visible si la línea dada es una tarea y no un procedimiento. Esto es regularmente el mismo que el comando / procedimiento que se muestra en la primera MANDO columna, aún cuando, a modo de ejemplo, Linux posibilita que una tarea cambie su nombre de comando, por lo que podría contener información adicional sobre la tarea. los USUARIO La columna enumera el usuario que inició el procedimiento / tarea.

A continuación tenemos una columna importante FD (Descriptor de archivo) que puede enumerar Número de descriptor de archivo o una cadena de texto específica que indique qué tipo de descriptor de archivo es. A modo de ejemplo, si ves cwd en esta columna, significa directorio de trabajo actual e indica que el procedimiento o la tarea dada tiene un candado abierto en el directorio de trabajo actual y que el directorio de trabajo se enumera debajo del NOMBRE columna.

Para obtener una lista completa de todos los posibles FD cadenas, tipo man lsof en su símbolo del sistema seguido de escribir / FD (con 3 espacios después de la barra y antes de FD) una vez dentro del manual, y posteriormente presionando INGRESAR para buscar la sección FD.

Cuando se trata de archivos normales, puede pensar en la FD columna como un contador, o un contador de ID único, comenzando en 0 y aumentando hasta el número total de archivos abiertos regulares en el sistema, con el número máximo de archivos abiertos definido por el ulimit -n ajuste, etc.

Al mirar archivos normales, el FD la columna, a modo de ejemplo, mostrará 102u o 13w. Estos dos ejemplos representan respectivamente el 102o archivo abierto en el sistema, en modo de acceso mixto de lectura / escritura, como lo indica el u indicador / etiqueta y el 13 ° archivo abierto en el sistema, solo en modo de acceso de escritura.

los ESCRIBE la columna es bastante autoexplicativa; indica si se mantiene un archivo normal o un bloqueo de directorio abierto. Hay varias otras etiquetas que podrían mostrarse aquí, y una búsqueda de / TYPE en man lsof (como se explicó previamente) proporcionará una lista completa.

los DISPOSITIVO La columna de forma general enumera los números de dispositivo, separados por comas, para la mayoría de los tipos de archivos. los SIZE/OFF columna es el tamaño del archivo, o el desplazamiento del archivo en bytes, y el NODO La columna comúnmente muestra el nodo de archivo o el número de inodo de archivo NFS de archivos locales. Además puede enumerar, a modo de ejemplo TCP o UDP cuando el candado dado es una conexión a Internet abierta.

Ejemplo: utilizar lsof con matar

Usando lsof en combinación con grep, awk y kill uno puede buscar un archivo específico en un sistema dado y posteriormente terminar el procedimiento (usando el PID, o identificador de procedimiento, descrito previamente).

Tenga en cuenta que esto solo debe hacerse en situaciones en las que tenga sentido hacerlo. A modo de ejemplo, puede tener un script Bash de subprocesos múltiples que inicie muchas subcapas diferentes donde cada una se aferra a un archivo determinado, y espera que uno de los subprocesos se cuelgue. Conoce el nombre de archivo abierto del procedimiento de suspensión, pero no sabe cuál es el PID para ese procedimiento / tarea es.

En tal situación, podemos ejecutar los siguientes comandos:

sudo su
lsof | grep 'some_file_descriptor' | awk '{print $2}' | xargs -I{} kill -9 {}

Pongamos esto en un ejemplo práctico. Supongamos que hemos creado el siguiente script test.sh en /tmp:

rm -Rf workspace
mkdir workspace
cd workspace
sleep 36000

Este script, cuando se ejecuta, creará un directorio llamado workspace, cambie los directorios a él con cd y posteriormente sleep durante 10 horas. Aunque a primera vista esto no parece abrir ningún archivo, recuerde la cwd Discutido antes; el script tiene un directorio de trabajo actual en uso, a saber /tmp/workspace!

Veamos cómo funciona esto en la práctica. Primero, definimos (usando su editor de texto favorito como vi) y posteriormente inicie el script en una sesión de terminal:

Ejecutando un script test.sh que contendrá directorios abiertos como los enumerados más adelante por lsof

A continuación, saltamos a una sesión de terminal secundaria / nueva y ejecutamos lsof, buscando el directorio de trabajo del script, a saber workspace:

lsof con un grep para el texto coincidente es una excelente manera de buscar la salida lsof detallada

Como podemos ver, lsof es capaz de hallar no solo nuestro script de prueba test.sh que tiene un cwd acoplarse /tmp/workspace, pero además vemos que sleep, comenzada desde dentro del guión, tiene un cwd abre el descriptor de archivo (o mejor directorio) en el mismo directorio.

Además podemos ver tanto el PID Para el test.sh guión así como para el sleep mando. Asumamos por un segundo que nuestro test.sh el script estaba colgado y queríamos terminarlo absolutamente de forma destructiva, dicho de otra forma, con kill -9 que es la forma más destructiva de terminar un procedimiento sin ningún nivel de cierre ordenado, y esto se basa en cualquier archivo abierto (o en nuestro caso, directorios abiertos) que contenía el script. Emitimos el siguiente comando desde el terminal secundario:

lsof | grep "workspace" | awk '{print $2}' | xargs -I{} kill -9 {}

Mata un proceso usando kill -9 basado en una búsqueda lsof usando grep

Este comando tomará la salida anterior y la analizará más. los awk '{print $2}' Simplemente muestrea la columna secundaria (los ID de procedimiento) y el xargs El comando pasará esta segunda columna a kill -9 (los {} en el comando será reemplazado por cualquier entrada xargs recibe).

Además podríamos anticipar que lsof cuenta con una línea de encabezado que contiene PID y este texto además se pasará a kill. Aunque no creará un obstáculo, un comando general mejor habría leído lsof | grep "workspace" | grep -v "PID" | awk '{print $2}' | xargs -I{} kill -9 {}, o alguna otra manera de filtrar la primera línea por completo.

El resultado en nuestra primera sesión de terminal principal es que nuestro script se elimina instantáneamente:

El script test.sh eliminó la salida como resultado de la eliminación ejecutada en la otra terminal

Si desea obtener más información sobre xargs, puede leer sobre el uso de xargs en combinación con bash -c para crear comandos complejos. Para la programación multiproceso de Bash, consulte Cómo usar el procesamiento multiproceso en scripts Bash.

Terminando

En este post exploramos el uso de lsof, el comando list open files y qué información representa cada una de las columnas en su salida predeterminada. Además analizamos un caso de uso práctico en el que usamos lsof en combinación con grep, awk y kill para hallar un archivo en particular (o en nuestro caso un directorio) que se mantiene abierto por un script y posteriormente terminar ese script cerrando así el directorio abierto.

Si disfrutó leyendo este post, eche un vistazo a nuestras afirmaciones, errores y bloqueos: ¿cuál es la diferencia? post.

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.