Ejecuta un comando de shell cuando se agrega un archivo

Tengo una carpeta llamada images en mi linux box. Esta carpeta está conectada a un sitio web y el administrador del sitio tiene la capacidad de agregar imágenes a este sitio. Sin embargo, cuando se agrega una imagen, quiero que se ejecute un comando para cambiar el tamaño de todas las imágenes de un directorio.

En resumen, quiero saber cómo puedo hacer que el servidor ejecute un comando específico cuando se agrega un nuevo archivo a una ubicación específica.

No sé cómo las personas están cargando contenido a esta carpeta, pero es posible que desee utilizar algo de tecnología más baja que la supervisión del directorio con inotify.

Si el protocolo es FTP y tiene acceso al registro de su servidor FTP, le sugiero que rastree ese registro para ver si se han subido correctamente. Este tipo de enfoque desencadenado por eventos será más rápido, más confiable y con menos carga que un método de sondeo con cron tradicional, y más portátil y más fácil de depurar que algo que use inotify.

La forma en que maneja esto, por supuesto, dependerá de su servidor FTP. Tengo uno corriendo vsftpd cuyos registros incluyen líneas como esta:

Fri May 25 07:36:02 2012 [pid 94378] [joe] OK LOGIN: Client "10.8.7.16" Fri May 25 07:36:12 2012 [pid 94380] [joe] OK UPLOAD: Client "10.8.7.16", "/path/to/file.zip", 8395136 bytes, 845.75Kbyte/sec Fri May 25 07:36:12 2012 [pid 94380] [joe] OK CHMOD: Client "10.8.7.16", "/path/to/file.zip 644" 

La línea de UPLOAD solo se agrega cuando vsftpd ha guardado el archivo correctamente. Podría analizar esto en un script de shell como este:

 #!/bin/sh tail -F /var/log/vsftpd.log | while read line; do if echo "$line" | grep -q 'OK UPLOAD:'; then filename=$(echo "$line" | cut -d, -f2) if [ -s "$filename" ]; then # do something with $filename fi fi done 

Si está utilizando una herramienta de carga HTTP, vea si esa herramienta tiene un archivo de registro de texto que usa para registrar archivos entrantes. Si no considera agregarle algún tipo de función de registrador, entonces generará registros que puede tail .

Al igual que John, comentó que la API de inotify es un punto de partida; sin embargo, es posible que le interesen algunas herramientas que usan esta API para realizar tareas de notificación de archivos:

Por ejemplo, incron, que se puede usar para ejecutar tareas tipo cron cuando se detectan cambios de archivos o directorios.

O inotify-tools, que es un conjunto de herramientas de línea de comandos que puede usar para crear su propio script de shell de notificación de archivos.

Si observa la parte inferior del Wiki pake para inotify-tools, verá referencias a aún más herramientas y soporte para lenguajes de nivel superior como Python, Perl o Ruby ( código de ejemplo ).

Es posible que desee ver inotify

La API inotify proporciona un mecanismo para supervisar los eventos del sistema de archivos. Inotify se puede usar para monitorear archivos individuales o para monitorear directorios. Cuando se supervisa un directorio, inotify devolverá eventos para el directorio en sí y para los archivos dentro del directorio.

Usando el trabajo de ghotis

Esto es lo que hice para que los usuarios tengan espacio libre:

 #!/bin/bash tail -F -n 1 /var/log/vsftpd.log | while read line; do if echo "$line" | grep -q 'OK LOGIN:'; then pid=$(sed 's/.*\[\([^]]*\)\].*/\1/g' < << "$line") #the operator '<<<' doesnt exist in dash so use bash if [[ $pid != *"pid"* ]]; then echo -e "Disk 1: Contains Games:\n" > /home/vftp/"$pid"/FreeSpace.txt; df -h /media/Disk1/ >> /home/vftp/"$pid"/FreeSpace.txt echo -e "\r\n\r\nIn order to read this properly you need to use a text editor that can read *nix format files" >> /home/vftp/"$pid"/FreeSpace.txt fi echo "checked" # awk '{ sub("\r$", ""); print }' /home/vftp/"$pid"/FreeSpace.txt > /home/vftp/"$pid"/FreeSpace.txt fi done 

Si el archivo se agrega a través de una carga HTTP, y si su servidor es apache, es posible que desee comprobar mod_security.

Le permite ejecutar un script para cada carga realizada a través de HTTP POST.

 #!/bin/bash tail -F -n0 /var/log/vsftpd.log | while read line; do if echo "$line" | grep -q 'OK UPLOAD:'; then filename=$(echo $line | cut -d, -f2 |awk '{print $1}') filename="${filename%\"}" filename="${filename#\"}" #sleep 1s if [ -s $filename ]; then # do something with $filename echo $filename fi fi done