¿Cómo ejecutar un comando cuando se actualizan los contenidos de un directorio?

27

Hay un directorio Acuyos contenidos son cambiados frecuentemente por otras personas.

Hice un directorio personal Bdonde guardo todos los archivos que alguna vez han estado A.

Actualmente, sólo de vez en cuando corro rsyncpara obtener los archivos a ser subidos del Aa B. Sin embargo, temo la posibilidad de que algunos archivos se agreguen Ay luego se eliminen Aantes de que tenga la oportunidad de copiarlos B.

¿Cuál es la mejor manera de evitar que esto ocurra? Idealmente, me gustaría que mi script de respaldo actual se ejecute cada vez que Ase cambie el contenido de .

oadams
fuente

Respuestas:

29

Si tiene instaladas las herramientas de inotify, puede usarlas inotifywaitpara activar una acción si se escribe un archivo o directorio en:

#!/bin/sh
dir1=/path/to/A/
while inotifywait -qqre modify "$dir1"; do
    /run/backup/to/B 
done

Donde el -qqinterruptor es completamente silencioso, -res recursivo (si es necesario) y -ees el evento para monitorear, en este caso modify. De man inotifywait:

modificar
Se guardó un archivo observado o un archivo dentro de un directorio observado.
jasonwryan
fuente
55
incrondTambién puede ser de interés.
Shawn J. Goff, el
1
Guay. ¿Acabo de poner el script anterior en mi bashrc para que se ejecute cuando inicie sesión? ¿Hay alguna otra forma en que pueda hacerlo funcionar todo el tiempo?
Oadams
Para iniciar sesión, sí /etc/profilepara todo el sistema o .bash_profilesolo para su usuario. Para ejecutarlo después del arranque, depende de su sabor de Unix / Linux; /etc/rc.local, /etc/rc.d/o/etc/init.d/
jasonwryan
1
Para directorios más grandes, es posible que desee considerar usar el --monitorconmutador (y canalizar la salida a su bucle en su lugar), de lo contrario, hay una sobrecarga cuando inotifywaitse inicia una y otra vez
Tobias Kienzler
¿Cuán confiable sería esta solución para ejecutar un script para cada archivo que se agregó en un árbol de directorios a través de un servidor FTP (digamos que se agrega un nuevo archivo cada 3 minutos en promedio y esto podría durar años)? Si no es muy, ¿hay una solución alternativa?
Nikola Novak
5

Estrictamente hablando, si alguien suelta un archivo y lo elimina muy rápidamente, es posible que se lo pierda. El uso de inotify (en Linux, o una característica similar en otros unices) hace que la ventana de riesgo sea pequeña.

Si puede montar el sistema de archivos de su elección en ese directorio (me doy cuenta de que esto puede no ser una opción), puede poner uno que registre todas las versiones de archivo, por ejemplo, copyfs .

Gilles 'SO- deja de ser malvado'
fuente
4

Pruebe la entrherramienta de línea de comandos que puede ejecutar comandos arbitrarios cuando cambian los archivos. Desde la versión 2.9, -dse agregó una opción de observación de directorio ( ) para reaccionar a los eventos cuando se agrega un nuevo archivo a un directorio.

Ejemplo para ejecutar la utilidad si se agrega un nuevo archivo al proyecto:

$ while true; do
> echo src/* | entr -d your_command
> done

En el modo de observación de directorio, el directorio padre de cada archivo se agrega implícitamente a la lista de observación.

La única implicación de esto es que si aparece un nuevo archivo, debe salir para permitir que un bucle de shell externo vuelva a escanear el sistema de archivos.

Aquí está la versión sin una opción de visualización de directorio:

$ while true; do
> echo src/* src | entr your_command
> done

Aquí hay un ejemplo más simple según sus necesidades:

$ ls -d * | entr sh -c 'rsync -vuar A B'

Visite el sitio web entrproject.org para más detalles.

kenorb
fuente