Cómo monitorizar eventos de un directorio en tiempo real con inotify en Linux

Publicado el 01 febrero 2018 por Drassill
En ocasiones podemos vernos en la situación de querer tener un control de lo que ocurre dentro de un directorio; tal es así el control que queremos que podemos llegar a desear ver todos los eventos en tiempo real que ocurren dentro de un directorio, eventos tales como el listado de archivos, la creación y modificación de estos e incluso la eliminación. Generalmente podemos intentar jugar el comando history para ver los últimos comandos, examinar las últimas fechas de modificación de los ficheros, e incluso examinar sus metadatos, con el fin de averiguar lo máximo posible de lo que ocurre en nuestro equipo; especialmente cuando éste está siendo accedido por varios usuarios a la vez o simplemente tenemos miedo de que lo esté siendo. Es por ello que para ocasiones como esas puede ser muy interesante recurrir a herramientas de observación de eventos en tiempo real para Linux tales como inotify.

Inotify es una herramienta con la capacidad de observar eventos en tiempo real dentro de un directorio, lo que nos otorga un gran conocimiento en comparación con otras herramientas, si bien, tal y como he matizado al principio, requiere monitorizar en tiempo real para poder ser funcional. Esta utilidad no está instalada por defecto en el sistema, sino que requiere ser instalada, si bien afortunadamente es realmente sencillo pues está incluida dentro de los repositorios oficiales del sistema:
apt-get install inotify-tools
Esto hará que se instalen dos herramientas: Inotifywait e Inotifywatch. El que nos interesa en concreto es Inotifywait pues ofrece una enorme información.
Un modo muy básico de usar Inotifywait sería de la siguiente forma:
inotifywait /tmp
El problema que tiene usar este comando directamente es que efectivamente escuchará los eventos de dicho directorio, pero no será capaz de escuchar los eventos de los subdirectorios de éste y además al recibir un solo evento inotifywait se cerraría automáticamente. Es por ello que conviene conocer cómo usarla para poder sacarle de verdad provecho.
Hay diferentes parámetros y opciones, pero los más importantes serían los de a continuación:

Comencemos con el parámetro -m; La inclusión de este parámetro hará que inotify entre en modo monitorización, con lo que podrá recibir eventos continuamente sin llegar a cerrarse a menos que nosotros le mandemos la señal necesaria para que se detenga. Dicho parámetro también podría especificarse también mediante --monitor. Otro parámetro muy útil sería el -r; Al usar este parámetro estaríamos indicando que se monitorizase todo el directorio en cuestión y también todos los subdirectorios. El parámetro en cuestión también podría especificarse mediante --recursive. El último que en mi opinión es también importante tener en cuenta sería el -e;Este último es más "opcional" que los dos anteriores, pero puede ser de una enorme utilidad, ya que sirve de filtrador de eventos; es decir que con dicho parámetro veríamos los eventos que nosotros queramos y no todos, que sería lo que se nos mostraría por defecto. El parámetro también puede ser llamado mediante --events. Obviamente, para poder filtrar los eventos, habría que conocer cuales son... Son un número considerable y, desgraciadamente, no todos son fáciles de recordar, pero es bueno conocer al menos su existencia:
  • access: Este sería uno de los más veríamos, ya que indica que un fichero o el contenido de un directorio ha sido leído. 
  • modify: Este parámetro haría que se nos notifique de los cambios que se realicen en el entorno que estamos monitorizando.
  • attrib: Este es ligeramente más raro que el resto, pues solamente notificaría los cambios en los atributos de los ficheros o directorios.
  • close_nowrite: Se notifica cuando se ha cerrado un fichero o directorio que ha sido abierto en modo solo lectura.
  • close_write: Se notifica cuando se cierra un fichero o directorio en modo escritura.
  • open: Especifica que un fichero o directorio ha sido abierto; este mensaje también es de los que más aparecen junto con access.
  • moved_to: Este evento implica que algo ha sido movido hacia el directorio que estamos monitorizando.
  • moved_from: Este evento indica que algo ha sido movido desde el directorio que estamos monitorizando.
  • move: Este evento indica que va a haber una actividad de movimiento dentro del directorio que monitorizamos, ya sea desde o hacia el directorio en cuestión.
  • create: En este caso se indicaría que algo (ya sea fichero o directorio) ha sido creado dentro del lugar que estamos monitorizando.
  • delete: Al contrario que create, en este caso se detectaría que algo se ha eliminado.
  • delete_self: Esto indica que el fichero o directorio que estamos monitorizando acaba de ser eliminado.
  • umount: Aquí se detectaría que el sistema de ficheros en que se aloja aquello que estamos monitorizando, acaba de ser desmontado.

Es conveniente resaltar que generalmente querremos ver todos los eventos, pero es importante conocer qué eventos se monitorizan para así poder hacer filtrados en caso de tener una necesidad muy concreta...
Teniendo estos conceptos claros podemos hacer cosas como la siguiente:
inotifywait -r -m /tmp
Con dicho comando estaríamos monitorizando todos los eventos dentro de la carpeta /tmp y todos sus subdirectorios; además estaría recibiendo constantemente eventos hasta que se le indique lo contrario, con lo que si abriésemos otra terminal podríamos realizar las acciones de a continuación:
cd /tmp & ls & touch test & echo prueba > test & rm test
Si viésemos los eventos visualizados por inotifywait veríamos lo siguiente:

Al final se estarían viendo en tiempo real todas las acciones realizadas, desde la creación del archivo hasta la eliminación de éste. Además si queremos podemos dejar que el proceso inotifywait esté corriendo en segundo plano y que vuelque todo el contenido en fichero para poder analizarlo más tarde con tranquilidad, extrayendo las conclusiones que deseemos. Esto requeriría hacer simplemente la siguiente modificación en el anterior comando:
inotifywait -r -m /tmp > /var/inotify.log &
Dicho proceso tendría que ser finalizado mediante un kill, o llevado a primer plano para poder finalizarse.
Como podéis ver el tener controlado un directorio o un grupo de éstos puede llegar a ser útil pues gracias a ello podemos tener un mayor conocimiento de lo que ocurre dentro de nuestro sistema.
Espero que os haya resultado útil.
Saludos.