¿Cómo ejecutar un script de shell cuando un archivo o directorio cambia?

Quiero ejecutar un script de shell cuando cambia un archivo o directorio específico.

¿Cómo puedo hacer eso fácilmente?

Use inotify-tools .

Uso esta secuencia de comandos para ejecutar una secuencia de comandos de construcción sobre los cambios en un árbol de directorios:

#! /bin/bash DIRECTORY_TO_OBSERVE="js" // might want to change this function block_for_change { inotifywait -r \ -e modify,move,create,delete \ $DIRECTORY_TO_OBSERVE } BUILD_SCRIPT=build.sh // might want to change this too function build { bash $BUILD_SCRIPT } build while block_for_change; do build done 

Utiliza inotify-tools . Compruebe la página de manual de inotifywait para inotifywait cómo personalizar qué desencadena la comstackción.

Puede probar la herramienta entr para ejecutar comandos arbitrarios cuando los archivos cambian. Ejemplo para archivos:

 $ ls -d * | entr sh -c 'make && make test' 

o:

 $ ls *.css *.html | entr reload-browser Firefox 

Para los directorios, use -d , pero debe usarlo en el ciclo, por ejemplo:

 while true; do find path/ | entr -d echo Changed; done 

o:

 while true; do ls path/* | entr -pd echo Changed; done 

Echa un vistazo al daemon del monitor del sistema de archivos kernel

http://freshmeat.net/projects/kfsmd/

Aquí hay un cómo hacerlo:

http://www.linux.com/archive/feature/124903

Como se mencionó, inotify-tools es probablemente la mejor idea. Sin embargo, si está progtwigndo para divertirse, puede intentar ganar XP de hacker mediante la aplicación juiciosa de tail -f .

Aquí hay otra opción: http://fileschanged.sourceforge.net/

Ver especialmente el “ejemplo 4”, que “monitorea un directorio y archiva los archivos nuevos o modificados”.

¿Qué tal este guion? Utiliza el comando ‘stat’ para obtener el tiempo de acceso de un archivo y ejecuta un comando siempre que haya un cambio en el tiempo de acceso (siempre que se acceda al archivo).

 #!/bin/bash while true do ATIME=`stat -c %Z /path/to/the/file.txt` if [[ "$ATIME" != "$LTIME" ]] then echo "RUN COMMNAD" LTIME=$ATIME fi sleep 5 done 

Solo para fines de depuración, cuando escribo un guión de shell y quiero que se ejecute en guardar, uso esto:

 #!/bin/bash file="$1" # Name of file command="${*:2}" # Command to run on change (takes rest of line) t1="$(ls --full-time $file | awk '{ print $7 }')" # Get latest save time while true do t2="$(ls --full-time $file | awk '{ print $7 }')" # Compare to new save time if [ "$t1" != "$t2" ];then t1="$t2"; $command; fi # If different, run command sleep 0.5 done 

Ejecútalo como

 run_on_save.sh myfile.sh ./myfile.sh arg1 arg2 arg3 

Edición: anteriormente probado en Ubuntu 12.04, para Mac OS, cambie las ls líneas a:

 "$(ls -lT $file | awk '{ print $8 }')" 

Agregue lo siguiente a ~ / .bashrc:

 function react() { if [ -z "$1" -o -z "$2" ]; then echo "Usage: react <[./]file-to-watch> <[./]action>  " elif ! [ -r "$1" ]; then echo "Can't react to $1, permission denied" else TARGET="$1"; shift ACTION="$@" while sleep 1; do ATIME=$(stat -c %Z "$TARGET") if [[ "$ATIME" != "${LTIME:-}" ]]; then LTIME=$ATIME $ACTION fi done fi } 
    Intereting Posts