I am trying to create a bash script with 2 parameters:
I want to watch the
METHOD 1:
#!/bin/sh
check() {
dir="$1"
chsum1=`digest -a md5 $dir | awk '{print $1}'`
chsum2=$chsum1
while [ $chsum1 -eq $chsum2 ]
do
sleep 10
chsum2=`digest -a md5 $dir | awk '{print $1}'`
done
eval $2
}
check $*
This script takes in two parameters [directory, command]. Every 10 seconds the script executes check()
to see it the folder has changed. If not it sleeps and the cycle repeats.
In the event that the folder has changed, it eval
s your command.
METHOD 2:
Use a cron to monitor the folder.
You'll have to install incron:
sudo apt-get install incron
And then your script will look something like this:
#!/bin/bash
eval $1
(You won't need to specify the folder since it will be the job of the cron to monitor the specified directory)
A full, working example can be found here:
http://www.errr-online.com/index.php/2011/02/25/monitor-a-directory-or-file-for-changes-on-linux-using-inotify/
#!/bin/bash
# Author: Devonte
# NGINX WATCH DAEMON
# Place file in root of nginx folder /etc/nginx
# This will test your nginx config on any change and
# if there are no problems it will reload your configuration
# USAGE: sh nginx-watch.sh
dir=`dirname $0`
checksum_initial=`tar -cf - $dir | md5sum | awk '{print $1}'`
checksum_now=$checksum_initial
# Start nginx
nginx
while true
do
sleep 3
checksum_now=`tar -cf - $dir | md5sum | awk '{print $1}'`
if [ $checksum_initial != $checksum_now ]; then
echo "[ NGINX ] A configuration file changed. Reloading..."
nginx -t && nginx -s reload;
fi
checksum_initial=$checksum_now
done
Why not using AppleScript
http://www.tuaw.com/2009/03/26/applescript-exploring-the-power-of-folder-actions-part-iii/
on adding folder items to this_folder after receiving added_items
tell application "Finder"
...
To continuously recursively monitor folder (md5) and execute a command on change:
daemon() {
chsum1=""
while [[ true ]]
do
chsum2=`find src/ -type f -exec md5 {} \;`
if [[ $chsum1 != $chsum2 ]] ; then
compile
chsum1=$chsum2
fi
sleep 2
done
}
Works on my OS X as I do not have digest
.
On Linux, you can use md5sum
as a replacement for the md5
command.
If you only need to check for files being created/deleted on top level (not checking subfolders) you might want to use the following.
It uses few ressources hence it can react quickly, I use it to check for a changed file.
#!/bin/bash
file="$1"
shift
tmp=$(mktemp)
trap 'rm "$tmp"' EXIT
while true; do
while [ ! "$tmp" -ot "$file" ]; do
sleep 0.5
done
eval "$@ &"
echo $! > "$tmp"
wait
done
I wrote a general utility called watchfile for simplifying these kinds of operations.
It is less powerfull than inotifywatch
, but I prefer a simpler, less verbose utility.
For the desired task, you want to monitor if any files in current directory have been modified. To list all files recursively in the current directory:
find . -type f
To output the timestamp information of each of these files:
find . -type f -print0 | xargs -0 stat
Now, you can monitor this output with the watchfile
utility and execute a command CMD
when this information changes:
watchfile -s "find . -type f -print0 | xargs -0 stat" -e CMD