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 ...".






Using a simple command line script and Marked to keep and display notes

I was reading this and it sparked an idea for the combined use of Marked and a command line script. I often would like to simply collect notes as I work at the command line. The notes can all go into the same file and I will sort them out afterwards (GTD "inbox" style). So the simple command line

function n() { echo "$(date): $*" >>~/Inbox/Note.txt; }
defines a "n" command that works well enough. Usage is simply to type "n this is my note" at the command line and the script will put the timestamp and the "this is my note" text in to the file ~/Inbox/Note.txt.

The spark, however, was that I could use Marked to display an automatically updated view of the note file's contents. Further, I could add a little markdown notation to the script to help visually separate the notes. The final script is

function n() { printf "\n### %s\n%s\n" "$(date)" "$*" >>~/Inbox/Note.txt; }
Here the date is formatted as a header and the note's text as a paragraph.

The end result is a window like this