¿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
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:
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
:
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 {}
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:
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.