Lsof es una potente herramienta disponible en la shell de Linux que lista los ficheros abiertos en el sistema. Partiendo de esta base, podemos conocer rápidamente que ficheros mantiene abiertos un determinado proceso (PID) o usuario e información adicional como el puerto utilizado por dichos servicios/ficheros, sockets en uso, etc.
Lanzando el comando lsof sin ningún parámetro listará todos los ficheros abiertos en la máquina en ese momento, no es recomendable ya que como imaginaréis saldrá una cantidad enorme.
Algunos de los ejemplos de uso más comunes son los siguientes:
Listar los ficheros abiertos de un determinado PID
# lsof -p PID
Ejemplo, vamos a listar los ficheros abiertos de un PID perteneciente a apache, también veremos los sockets y puertos en los que escucha el proceso:
# lsof -p 15826 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME httpd 15826 apache cwd DIR 8,2 4096 2 / httpd 15826 apache rtd DIR 8,2 4096 2 / httpd 15826 apache txt REG 8,2 312340 6764473 /usr/sbin/httpd httpd 15826 apache DEL REG 8,2 6761188 /usr/lib/libldap-2.3.so.0.2.15.#prelink#.MN10ei httpd 15826 apache mem REG 8,2 1009712 8585265 /lib/libdb-4.3.so httpd 15826 apache mem REG 8,2 125744 8589007 /lib/libpthread-2.5.so httpd 15826 apache mem REG 8,2 15704 8585423 /lib/libuuid.so.1.2 httpd 15826 apache mem REG 8,2 6764446 /usr/lib/libpq.so.4.1 (path inode=6765089) httpd 15826 apache mem REG 8,2 101404 8589003 /lib/libnsl-2.5.so httpd 15826 apache mem REG 8,2 133056 8589019 /lib/libexpat.so.0.5.0 httpd 15826 apache mem REG 8,2 190712 6764712 /usr/lib/libgssapi_krb5.so.2.2 httpd 15826 apache mem REG 8,2 16428 8589004 /lib/libdl-2.5.so httpd 15826 apache mem REG 8,2 281116 8585251 /lib/libssl.so.0.9.8b httpd 15826 apache mem REG 8,2 75028 6751429 /usr/lib/libz.so.1.2.3 httpd 15826 apache mem REG 8,2 33648 6764709 /usr/lib/libkrb5support.so.0.1 httpd 15826 apache mem REG 8,2 7880 8585403 /lib/libkeyutils-1.2.so httpd 15826 apache mem REG 8,2 5500 6981504 /usr/lib/httpd/modules/mod_authn_file.so httpd 15826 apache mem REG 8,2 1597968 8588999 /lib/libc-2.5.so [...]
Como veis muestra información de gran utilidad como el servicio/comando al que pertenece el proceso (COMMAND), el PID, usuario que lo está ejecutando (USER), el descriptor de archivo (FD), tipo de nodo asociado con el fichero (TYPE), número de dispositivo (DEVICE), el tamaño del fichero y el nombre/ruta al mismo.
Echad un vistazo a las páginas man (man lsof) para ver una descripción extendida de cada columna.
Listar ficheros abiertos en un dispositivo o partición:
Para evitar el típico fallo de no poder desmontarlo porque la partición o el dispositivo está en uso:
# lsof /particion
Listar ficheros abiertos de un determinado usuario:
# lsof -u alex COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME gnome-key 2862 alex cwd DIR 8,3 4096 107912 /var/lib/gdm gnome-key 2862 alex rtd DIR 8,3 4096 2 / gnome-key 2862 alex txt REG 8,3 588132 6979 /usr/bin/gnome-keyring-daemon gnome-key 2862 alex mem REG 8,3 42974 76307 /usr/share/locale-langpack/es/LC_MESSAGES/glib20.mo gnome-key 2862 alex mem REG 8,3 133662 76393 /usr/share/locale-langpack/es/LC_MESSAGES/libc.mo gnome-key 2862 alex mem REG 8,3 42504 6194 /lib/tls/i686/cmov/libnss_files-2.9.so gnome-key 2862 alex mem REG 8,3 38444 6198 /lib/tls/i686/cmov/libnss_nis-2.9.so gnome-key 2862 alex mem REG 8,3 87804 6188 /lib/tls/i686/cmov/libnsl-2.9.so gnome-key 2862 alex mem REG 8,3 30436 6190 /lib/tls/i686/cmov/libnss_compat-2.9.so gnome-key 2862 alex mem REG 8,3 30765 76316 /usr/share/locale-langpack/es/LC_MESSAGES/gnome-keyring.mo gnome-key 2862 alex mem REG 8,3 256316 13609 /usr/lib/locale/es_ES.utf8/LC_CTYPE gnome-key 2862 alex mem REG 8,3 54 13614 /usr/lib/locale/es_ES.utf8/LC_NUMERIC [...]
Ver actividad de red en tiempo real
Pese a que hay otras herramientas más indicadas para este tipo de tareas (véase iptraf, iftop o tcpdump), lsof permite visualizar los puertos TCP y UDP en escucha así como las conexiones activas en el sistema. Para ello utilizamos el parámetro «-i»
# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rsyslogd 917 syslog 3u IPv4 7084 0t0 UDP *:syslog rsyslogd 917 syslog 4u IPv6 7085 0t0 UDP *:syslog avahi-dae 942 avahi 13u IPv4 8851 0t0 UDP *:mdns avahi-dae 942 avahi 14u IPv6 8852 0t0 UDP *:mdns avahi-dae 942 avahi 15u IPv4 8853 0t0 UDP *:47513 avahi-dae 942 avahi 16u IPv6 8854 0t0 UDP *:52390 iked.real 1199 root 15u IPv4 8967 0t0 UDP *:isakmp iked.real 1199 root 16u IPv4 8968 0t0 UDP *:4500 cupsd 1379 root 5u IPv6 10596 0t0 TCP ip6-localhost:ipp (LISTEN) cupsd 1379 root 6u IPv4 10597 0t0 TCP localhost:ipp (LISTEN) vpnagentd 1572 root 12u IPv4 10026 0t0 TCP localhost:29754 (LISTEN) dhclient 1672 root 6u IPv4 10193 0t0 UDP *:bootpc teamviewe 1681 root 14u IPv4 11369 0t0 TCP localhost:5939 (LISTEN) firefox 1964 foo 65u IPv4 250845 0t0 TCP www.test.com:54980->kix01s04-in-f15.1e100.net:https (CLOSE_WAIT)
Si no queremos ver la actividad en tiempo real sino una foto del momento en el que ejecutamos el comando, los parámetros a especificar son:
# lsof -P -i -n
Comprobar servicios/puertos que están escuchando
lsof -i -nP COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME portmap 2139 rpc 3u IPv4 5220 UDP *:111 portmap 2139 rpc 4u IPv4 5221 TCP *:111 (LISTEN) rpc.statd 2164 rpcuser 3u IPv4 5285 UDP *:647 rpc.statd 2164 rpcuser 6u IPv4 5264 UDP *:644 rpc.statd 2164 rpcuser 7u IPv4 5297 TCP *:650 (LISTEN) sendmail 2437 root 4u IPv4 1484615119 TCP 127.0.0.1:25 (LISTEN) mysqld 2753 mysql 10u IPv4 615583079 TCP *:3306 (LISTEN) httpd 3063 root 3u IPv6 583456545 TCP *:80 (LISTEN) httpd 3063 root 5u IPv6 583456550 TCP *:443 (LISTEN)
Ver archivos abiertos por un proceso o programa concreto
Con el parámetro «-c» podemos visualizar los archivos abiertos por un proceso en ejecución así como los puertos en los que está escuchando y sus conexiones establecidas. El siguiente ejemplo muestra los archivos y conexiones del proceso cupsd:
# lsof -c cupsd COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME cupsd 1379 root cwd DIR 8,5 4096 2 / cupsd 1379 root rtd DIR 8,5 4096 2 / cupsd 1379 root txt REG 8,5 436656 268733 /usr/sbin/cupsd cupsd 1379 root mem REG 8,5 51728 4775 /lib/x86_64-linux-gnu/libnss_files-2.13.so cupsd 1379 root mem REG 8,5 47680 4758 /lib/x86_64-linux-gnu/libnss_nis-2.13.so cupsd 1379 root mem REG 8,5 35712 4774 /lib/x86_64-linux-gnu/libnss_compat-2.13.so cupsd 1379 root mem REG 8,5 14280 59509 /lib/x86_64-linux-gnu/libgpg-error.so.0.8.0 cupsd 1379 root mem REG 8,5 10160 59511 /lib/x86_64-linux-gnu/libkeyutils.so.1.3 cupsd 1379 root mem REG 8,5 31104 264844 /usr/lib/x86_64-linux-gnu/libkrb5support.so cupsd 1379 root 5u IPv6 10596 0t0 TCP ip6-localhost:ipp (LISTEN) cupsd 1379 root 6u IPv4 10597 0t0 TCP localhost:ipp (LISTEN) [...]
Ver archivos en uso por un usuario en un directorio/path concreto
El siguiente ejemplo muestra un listado de los archivos en uso dentro del filesytem /tmp por parte del usuario «foo»:
# lsof -u foo -a +D /tmp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gnome-key 1872 foo 5u unix 0xffff8801266909c0 0t0 11778 /tmp/keyring-Ed3q50/control gnome-key 1872 foo 9u unix 0xffff88012b929d40 0t0 14609 /tmp/keyring-Ed3q50/pkcs11 gnome-key 1872 foo 10u unix 0xffff8801183f56c0 0t0 14638 /tmp/keyring-Ed3q50/ssh ssh-agent 1920 foo 3u unix 0xffff88011bfb2700 0t0 12569 /tmp/ssh-lFsqTbDh1891/agent.1891 xfce4-ses 1940 foo 8u unix 0xffff88011bfb0d00 0t0 12592 /tmp/.ICE-unix/1940 [...]
Visualizar archivos abiertos de un directorio/path concreto
El parámetro «+D» seguido de un path muestra los archivos abiertos de esa ruta especificada. Por ejemplo, para mostrar los archivos abiertos y por quien en /etc:
# lsof +D /etc COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME avahi-dae 942 avahi cwd DIR 8,5 4096 53003 /etc/avahi avahi-dae 942 avahi rtd DIR 8,5 4096 53003 /etc/avahi Xorg 1074 root cwd DIR 8,5 4096 52995 /etc/X11 sh 1891 foo 10r REG 8,5 9892 55384 /etc/xdg/xfce4/xinitrc applet.py 2026 foo 12u REG 8,5 1851 4437 /etc/passwd soffice.b 3581 foo 52r REG 8,5 1851 4437 /etc/passwd [...]
Esto son solo algunos ejemplos de lo útil que puede resultar este comando, os recomiendo trastear un poco con él y veréis como seguro le sacáis partido en muchas ocasiones. En algunos casos las mismas tareas se pueden realizar con otros comandos de forma más óptima (netstat por ejemplo), aunque nunca viene mal conoer varias formas de ejecutar una misma tarea. Y recordad:
man lsof