Cómo realizar una tarea cuando se agrega un archivo nuevo a un directorio en Linux

Bash shell en el concepto de PC Ubuntu
Fatmawati Achmad Zaenuri / Shutterstock.com

Este tutorial le mostrará cómo usar los eventos del sistema de archivos de Linux (notificar) para recibir notificaciones cada vez que aparece un archivo en un directorio. Puede utilizarlos como disparadores para automatizar tareas comunes en su sistema.

Vamos a escribir un script que observe un directorio y actúe sobre los archivos nuevos que se agregan. Cada archivo se comprime con gzip y se mueve a otro directorio, tan pronto como se detecta. El script usa el subsistema inotify, a través de una utilidad llamada inotify-tools. Pero primero, instalemos la herramienta y experimentemos.

Instalación de inotify-tools y gzip

Úselo apt-getpara instalar este paquete en su sistema si está usando Ubuntu u otra distribución basada en Debian. En otras distribuciones de Linux, utilice la herramienta de administración de paquetes de su distribución de Linux.

sudo apt-get install inotify-tools gzip

Experimentando con inotify-tools

Comencemos por observar un directorio y ver qué eventos se inician cuando llegan nuevos archivos. Usaremos una herramienta llamada   inotifywatch, que es parte de inotify-tools. Cree un nuevo directorio llamado «entrante»:

mkdir entrante

Comience a ver este directorio ejecutando el siguiente comando:

inotifywatch -v entrante

Esto le indicará a inotify que observe todos los eventos del sistema de archivos en el directorio «entrante». La -vopción hace que la herramienta imprima información adicional sobre lo que está haciendo. No hemos especificado una opción de tiempo de espera (-t), y el comando seguirá recopilando eventos hasta que salgamos con CTRL + C. En este punto, nuestra terminal debería verse así:

Abra una nueva ventana de terminal (o pestaña) y cambie al directorio entrante. Utilice el comando táctil para crear un nuevo archivo llamado «newfile».

cd entrante /
toque nuevo archivo

Ahora regrese a la primera ventana de terminal y detenga inotifywatch presionando CTRL + C.

Relacionado:  Cómo usar el comando cd en Linux

Se enviará una tabla de eventos a la consola, indicando una instancia de «crear», «abrir», «attrib» y «cerrar_escribir». Estos cuatro eventos ocurrieron cuando usamos la función táctil para crear un nuevo archivo, establecimos sus atributos de acceso al archivo, lo abrimos para escribir un carácter de terminación nulo y luego lo cerramos. Estos son solo algunos de la multitud de eventos que se pueden monitorear en un sistema de archivos con inotify-tools. Puede ver la lista completa en la página principal de inotifywatch.

Para nuestros propósitos, solo nos interesan dos eventos:

  • «Crear»: cuando se crea un archivo en el directorio de destino.
  • «Moved_to»: cuando un archivo se mueve desde otra ubicación al directorio de destino.

Intentemos inotifywatch nuevamente, pero esta vez indicándole que monitoree estos dos eventos solamente. Ejecute este comando en la primera ventana de terminal:

inotifywatch -v -e create -e moved_to entrante

En la segunda ventana o pestaña de la terminal, intentemos crear un nuevo archivo, cambiar su contenido y luego mover el archivo desde otra ubicación al directorio de destino. Todos estos comandos se ejecutan desde el directorio de inicio.

toque entrante / creado
echo Testing123 >> entrante / creado
toque / tmp / created2
mv / tmp / created2 entrante /

Regrese a la primera ventana de terminal y detenga inotifywatch presionando CTRL + C. Veremos el siguiente resultado:

Solo se contaron dos eventos: crear un archivo llamado «created.txt» y mover un archivo existente llamado «created2.txt». Todo lo demás, como modificar «created.txt», fue ignorado.

Ver un directorio y ejecutar una tarea

Ahora que sabemos qué eventos seguir, podemos usar otra herramienta llamada   inotifywaitpara bloquear la ejecución hasta que se cree un archivo o se mueva a nuestro directorio de destino. Usaremos los mismos argumentos que usamos con inotifywatch y también especificaremos cómo queremos que se formatee el nombre del archivo para usarlo en nuestra tarea.

Relacionado:  Cómo crear un archivo de intercambio en Linux

Antes de comenzar, necesitamos un directorio para contener los archivos que ya se han procesado. Cree un directorio llamado «procesado»:

mkdir procesado

A continuación, cree una nueva secuencia de comandos llamada «watch-incoming.sh» y agregue los contenidos que se enumeran a continuación:

#! / bin / bash

OBJETIVO = ~ / entrante /
PROCESADO = ~ / procesado /

inotifywait -m -e create -e moved_to --format "% f" $ TARGET \
        | mientras lee FILENAME
                hacer
                        echo Detectado $ FILENAME, moviéndose y comprimiendo
                        mv "$ TARGET / $ FILENAME" "$ PROCESSED / $ FILENAME"
                        gzip "$ PROCESSED / $ FILENAME"
                hecho

El script ejecuta el   inotifywaitcomando con la -mopción. Esto hace que el monitor de comandos cambie indefinidamente. Cada vez que se detecta un nuevo evento, el nombre del archivo se pasa al comando de lectura y se inyecta en la variable «FILENAME». Se ejecuta el bloque bajo el ciclo while, en el que el archivo se mueve primero al directorio «procesado» y luego se comprime con gzip. El archivo original se reemplaza por el archivo comprimido y el nombre del archivo terminará en «.gz».

Concedamos permisos de ejecución en este script y ejecútelo desde nuestro directorio de inicio.

chmod u + x watch-incoming.sh
./watch-incoming.sh

Abra la segunda ventana de terminal y cree un nuevo archivo en el directorio «entrante». Enumere el contenido del directorio «entrante» y «procesado» para ver los resultados del evento detectado:

El archivo de texto sin procesar que copiamos en el directorio «entrante» fue detectado por el script, copiado en «procesado» y luego comprimido usando gzip.

Podemos hacer algunas tareas interesantes ahora que podemos estar atentos a la llegada de nuevos archivos a un directorio. Por ejemplo, podríamos agregar una marca de agua a los archivos de imagen, comprimir videos sin procesar en formato mp4 e incluso cargar cada archivo nuevo que vemos en un bucket de Amazon S3. Este script es un buen punto de partida para implementar sus propios flujos de trabajo y automatizar tareas comunes en su sistema.

Relacionado:  Cómo usar el comando de unión en Linux