programas - scripts linux ejercicios resueltos
¿Cómo ejecutar un script de shell cuando un archivo o directorio cambia? (9)
¿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
Quiero ejecutar un script de shell cuando cambia un archivo o directorio específico.
¿Cómo puedo hacer eso fácilmente?
Agregue lo siguiente a ~ / .bashrc:
function react() {
if [ -z "$1" -o -z "$2" ]; then
echo "Usage: react <[./]file-to-watch> <[./]action> <to> <take>"
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
}
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".
Como se mencionó, inotify-tools es probablemente la mejor idea. Sin embargo, si está programando para divertirse, puede intentar ganar XP de hacker mediante la aplicación juiciosa de tail -f .
Echa un vistazo al daemon del monitor del sistema de archivos kernel
http://freshmeat.net/projects/kfsmd/
Aquí hay un cómo hacerlo:
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
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 }'')"
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 compilación.