En los sistemas operativos FreeBSD/OpenBSD, la herramienta fstat permite listar los archivos abiertos por un proceso pasando un PID como parámetro.
El utilitario fstat
identifica los archivos abiertos. Un archivo se considera abierto por un procesos si fue explícitamente abierto, si es el directorio de trabajo actual, si es el directorio raíz, si es el directorio raíz de un jail, si es el archivo ejecutable o la traza del kernel para dicho proceso.
Cuando se ejecuta sin opciones, fstat
reporta todos los archivos abiertos en el sistema.
Sin embargo, al utilizar la opción -p
, es posible listar todos los archivos abiertos por un proceso específico. Sólo basta pasar su PID (process ID) como parámetro. Veamos un ejemplo:
root@fbsd:~ # ps aux | grep 'syslo[g]' root 602 0.0 0.0 6416 2428 - Ss 15Oct19 4:03.79 /usr/sbin/syslogd -s
El proceso corriendo el demonio de syslogd tiene PID 602. Es posible conocer todos los archivos que tiene abiertos con fstat
:
root@fbsd:~ # fstat -p 602 USER CMD PID FD MOUNT INUM MODE SZ|DV R/W root syslogd 602 text / 552990 -r-xr-xr-x 45304 r root syslogd 602 wd / 4 drwxr-xr-x 28 r root syslogd 602 root / 4 drwxr-xr-x 28 r root syslogd 602 0 /dev 26 crw-rw-rw- null rw root syslogd 602 1 /dev 26 crw-rw-rw- null rw root syslogd 602 2 /dev 26 crw-rw-rw- null rw root syslogd 602 3 / 20528 -rw------- 3 w root syslogd 602 4* local dgram fffff8004f2422d0 root syslogd 602 5* local dgram fffff8004f143870 root syslogd 602 6* internet6 dgram udp fffff8003dd781d0 root syslogd 602 7* internet dgram udp fffff8003dd78000 root syslogd 602 8 /dev 37 crw------- klog r root syslogd 602 10 /dev 11 crw------- console w root syslogd 602 11 /var/log 4215 -rw-r--r-- 51526 w root syslogd 602 12 /var/log 1083 -rw------- 251846 w root syslogd 602 13 /var/log 4213 -rw------- 14149 w root syslogd 602 14 /var/log 1054 -rw-r----- 391 w root syslogd 602 15 /var/log 15 -rw-r--r-- 71 w root syslogd 602 16 /var/log 21 -rw------- 71 w root syslogd 602 17 /var/log 1032 -rw------- 46288 w root syslogd 602 18 /var/log 3563 -rw------- 3951 w root syslogd 602 19 /var/log 18 -rw-r----- 71 w
La columna "FD" identifica el número de descriptor de archivo en la tabla de archivos abiertos por proceso, o alguno de los siguientes valores especiales:
jail - jail root directory mmap - memory-mapped file root - root inode text - executable text inode tr - kernel trace file wd - current working directory
Si el número en esta columna contiene un asterisco, significa que se trata de un pipe, socket, o hay un error.
El inconveniente con esta herramienta es que no muestra el nombre de cada archivo abierto, sino sólo su número de inodo en el sistema de archivos de la columna "MOUNT". Si se requiere conocer la ruta o nombre del archivo, será necesario hacer una búsqueda por inodo con find
. Por ejemplo, en la salida anterior, el descriptor de archivo número 11 corresponde con el inodo 4215 en el sistema de archivos /var/log
:
root@fbsd:~ # find /var/log/ -inum 4215 /var/log/messages
Es posible automatizar la búsqueda del nombre para todos los archivos abiertos utilizando el siguiente one-liner:
root@fbsd:~ # fstat -p 602 | tail -n +5 | grep -v '*' | awk '{printf($4 ": "); system("find " $5 " -inum " $6 " -print -quit")}' 0: /dev/null 1: /dev/null 2: /dev/null 3: /var/run/syslog.pid 8: /dev/klog 10: /dev/console 11: /var/log/messages 12: /var/log/security 13: /var/log/auth.log 14: /var/log/maillog 15: /var/log/lpd-errs 16: /var/log/xferlog 17: /var/log/cron 18: /var/log/debug.log 19: /var/log/ppp.log
Primero se obtiene la salida de fstat
. Luego se eliminan las primeras 5 filas (ajustar este número dependiendo de cada proceso) con el objetivo de obtener sólo los PID válidos, y se filtran aquellos que contengan asterisco. Finalmente se utiliza awk
para armar el comando que hace la búsqueda con find
. Los parámetros -print -quit
en el comando find
se utilizan para que la búsqueda se detenga al obtener la primera coincidencia.
De esta forma se obtiene la lista de todos los archivos abiertos por un proceso en particular en un sistema FreeBSD u OpenBSD.
Para más información, consultar las páginas de manual de fstat
, awk
y find
:
man fstat
man awk
man find