A simple monitor with SMS messaging

Now and then you need to watch a directory for changes. For me, this is mostly to ensure a data build is continuing. When the directory size remains constant then it is likely that the data build has failed. A simple monitor is to regularly check the directory's size and send an email message should it not change. If the email is to a email-to-SMS service then you will know sooner about the problem.

To regularly check use cron. While you can have a program that loops over the check and then sleeps for an interval this is very likely to fail at some time, that is, the program dies without warning. Cron will not fail in this way.

Since you are interested in change you need to record the previous value to compare to the new value. Just use a file. Anything else will likely fail.

So here is your crontab line (place all lines on one line) to run the command several times per hour


*/5 * * * * $HOME/bin/watch-directory-and-mail
-t 1234567890@txt.att.net
-o $HOME/var/data-2012-09-18.watch
-w $HOME/var/data-2012-09-18/

This says to watch the directory "$HOME/var/data-2012-09-18/", keep the record of previous directory size in "$HOME/var/data-2012-09-18.watch", and to raise an alarm by sending email to "1234567890@txt.att.net" (AT&T's email-to-SMS service). The "$HOME/bin/watch-directory-and-mail" script is


#!/bin/bash

function send-message() {
echo "$3" | mail -s "$2" "$1" >/dev/null 2>&1
}

TO="$USER"
WATCH="$(pwd)"
OUTPUT="$WATCH.watch"
SUBJECT="$(basename $WATCH)"

while getopts "t:s:w:o:h" opt
do
case $opt in
t) TO=$OPTARG ;;
w) WATCH=$OPTARG ;;
o) OUTPUT=$OPTARG ;;
s) SUBJECT=$OPTARG ;;
*) echo "usage: $(basename $0) \
-t email \
-s subject \
-w directory/file \
-o status-file" ;;
esac
done

V1=$(du -s $WATCH|cut -f 1)
if [ -r "$OUTPUT" ]
then
V0=$(cat "$OUTPUT")
if [ $V0 -eq $V1 ]
then
send-message $TO $SUBJECT "$(basename $WATCH) unchanged size at $V1"
fi
else
send-message $TO $SUBJECT "$(basename $WATCH) initial size is $V1"
fi

echo $V1 >$OUTPUT

# END

Update: The script works just as well with a file as with a directory. If the rate of growth of the directory/file is slow then use "du -sb" to get byte counts. (OS X's du does not have the -b option.)

Update: If you have multi watching going on then the message sent is not very helpful. Have updated the code to enable to use to specify the message.

Update: If you don't want the script txting you during the night then change the crontab schedule to 9 AM to 5 PM, eg "*/5 8-17 * * * $HOME/bin/watch-directory-and-mail ...".