A menudo es necesario recurrir a nuestro ingenio para resolver problemas puntuales sobre sistemas en los que no se puede realizar modificaciones. Por ejemplo, cierto sistema genera una salida en formato de texto plano y el cliente requiere que el formato sea PDF. Al mismo tiempo, este sistema es de código cerrado, con lo cual no es posible modificar o adaptar la aplicación existente. Sin embargo, en Linux, es posible crear un pequeño programa secundario que se encargue de convertir a formato PDF el archivo *.txt generado. El inconveniente es: ¿cómo saber cuándo se ha creado un nuevo archivo y cuál es su nombre? Es aquí donde se viene la API inotify del kernel Linux al rescate.

inotify (inode notify) es un subsistema del kernel Linux que provee una API con un mecanismo para monitorear eventos en el sistema de archivos. Puede ser utilizado para monitorear archivos individuales o directorios. Cuando se utiliza para monitorear un directorio, inotify retorna eventos asociados al directorio en sí mismo y a todos los archivos que contiene.

Por otro lado, la herramienta inotifywait permite esperar por cambios en archivos haciendo uso de la API de inotify. Esta herramienta es muy adecuada para esperar cambios en archivos desde scripts, y puede finalizar al primer evento que ocurra o monitorear de manera continua imprimiendo los eventos a medida que ocurren.

Un caso real

El problema es el siguiente: la aplicación genera archivos .txt en el directorio /var/www/impresiones/ cuyos nombres no son predecibles y se requiere que sean convertidos a PDF automática e inmediatamente. No es posible convertirlos periódicamente (digamos, utilizando un cronjob cada una hora, por poner un ejemplo) sino que el requisito es que sean convertidos en tiempo real, en el momento preciso en el que son creados.

A tal fin se puede utilizar inotifywait en modo de monitoreo continuo (-m) de los eventos (-e) close_write (se cerró un archivo que fue abierto en modo de escritura) y moved_to (un archivo o directorio fue movido al directorio monitoreado) sobre el directorio donde se generarán los archivos de texto plano en tiempo real.

inotifywait reportará por salida estándar cada vez que uno de estos eventos ocurra. Luego es posible personalizar el formato de dicha salida mediante la opción --format. Como sólo me interesa saber el nombre del archivo modificado/creado, utilizo el formato %f (nombre del archivo asociado al evento).

Luego sólo basta recuperar el nombre del archivo y (si es un archivo con extensión .txt) convertirlo a formato PDF utilizando enscript.

El script Bash resultante es el siguiente:

#!/bin/bash
# Script para convertir automáticamente archivos .txt a PDF
# Cada vez que se crea un archivo con extensión .txt en el directorio $ORIGEN
# lo convierte a PDF y lo guarda en el directorio $DESTINO

ORIGEN="/var/www/impresiones/"
DESTINO="/var/www/impresiones/PDF"

inotifywait -q -m -e close_write,moved_to --format %f $ORIGEN |
while read ARCHIVO; do
  TXT="$ORIGEN$ARCHIVO"
  case $TXT in
    *.txt)
      # Convertir el archivo .txt a PS
      enscript -M A4 --margins=1:1:1:1 -f Courier7 $TXT -p ${TXT%.txt}.ps 2>/dev/null
      # Convertir el PS a PDF
      ps2pdf ${TXT%.txt}.ps
      mv ${TXT%.txt}.pdf $DESTINO
  esac
done

Así como en este ejemplo se convierte o genera el archivo PDF asociado al .txt es posible ejecutar cualquier otra herramienta o realizar cualquier otra acción que se desee.

Referencias

  • man inotify
  • man inotifywait


Tal vez pueda interesarte


Compartí este artículo