-
-
Save senko/1154509 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# | |
# Watch current directory (recursively) for file changes, and execute | |
# a command when a file or directory is created, modified or deleted. | |
# | |
# Written by: Senko Rasic <[email protected]> | |
# | |
# Requires Linux, bash and inotifywait (from inotify-tools package). | |
# | |
# To avoid executing the command multiple times when a sequence of | |
# events happen, the script waits one second after the change - if | |
# more changes happen, the timeout is extended by a second again. | |
# | |
# Installation: | |
# chmod a+rx onchange.sh | |
# sudo cp onchange.sh /usr/local/bin | |
# | |
# Example use - rsync local changes to the remote server: | |
# | |
# onchange.sh rsync -avt . host:/remote/dir | |
# | |
# Released to Public Domain. Use it as you like. | |
# | |
EVENTS="CREATE,CLOSE_WRITE,DELETE,MODIFY,MOVED_FROM,MOVED_TO" | |
if [ -z "$1" ]; then | |
echo "Usage: $0 cmd ..." | |
exit -1; | |
fi | |
inotifywait -e "$EVENTS" -m -r --format '%:e %f' . | ( | |
WAITING=""; | |
while true; do | |
LINE=""; | |
read -t 1 LINE; | |
if test -z "$LINE"; then | |
if test ! -z "$WAITING"; then | |
echo "CHANGE"; | |
WAITING=""; | |
fi; | |
else | |
WAITING=1; | |
fi; | |
done) | ( | |
while true; do | |
read TMP; | |
echo $@ | |
$@ | |
done | |
) |
Unfortunately inotifywait
does not work with mounted folders. I wanted to use it in my vagrant box, to copy files from eg. /vagrant/www/
to /var/www/
(which is the document root of apache). Mounting files directly to document root slows down php very much, so I thought this would be a nice idea.
@ArminVieweg Did you eventually find a solution for that? It's precisely what I was looking to do.
The version with eval
published by @evgenius https://gist.github.com/evgenius/6019316
What will be the benefit of running onchange.sh every x minutes (to trigger rsync) versus running rsync every x minutes? Is it just less demanding on the server?
Because not everyone runs Mac?
Why can't I kill it with ctrl + c?
Nice script! Thanks 👍
I'm using rsync to synchronize my local dir to a remote server's dir, which is working great, but I have to enter my password on every sync. Any ideas on how I could sync fully automatically (without having to enter the password)?
Unfortunately I can't setup an ssh key and use it to authenticate, since the remote is shared and crappy..
Cool idea, but how would you pass extra arguments with quotes? say i want onchange.sh rsync -a --exclude='folder with space' host:/path
?
Thanks for the script! I'm having trouble figuring out where the 1 second is defined, as I'd like to extend it.
@tdmalone, read -t 1 LINE
tries to read one line, but with a one second timeout. read
is a bash
builtin, and is documented on the bash
man page.
Thanks! I modified this script, now it can use entered path, not current directory only =)
Changes there : https://gist.github.com/AVAtarMod/e8bb8ee64cdb009f68d2f70615632b62
15 minutes
!/bin/bash
if [ "$1"x = ""x ]; then
cat<<EOF
Watches for changes recursively, then goes on to execute your command
or script. It wait 2.5 minutes between executes. Good for syncing
directories or doing dynamic backups.
by Hydranix
Usage: DetectChanges "[ directory to watch ]" "[ command/script to execute ]" "[optional: time in second between executes]"
EOF
exit 0;
fi
while [ ! -f /tmp/EXITHNx ]; do
sleep 3
inotifywait -r -e create -e delete -e move "${1}" &>/dev/null
XSTA=$?
if [ "$XSTA" = "0" ]; then
eval ${2}
else
touch /tmp/EXITHNx
exit 1
fi
[[ -z ${3} ]] && sleep 150 || sleep ${3}
done
rm -f /tmp/EXITHNx