Skip to content

Instantly share code, notes, and snippets.

@colinmollenhour
Created June 24, 2010 03:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save colinmollenhour/450941 to your computer and use it in GitHub Desktop.
Save colinmollenhour/450941 to your computer and use it in GitHub Desktop.
Monitor File Script
#!/bin/bash
#
# Colin Mollenhour
#
# Run this from a cron job to be notified when a file is changed.
# Use the --append-new option to append new content to the notification email.
#
# Examples:
#
# # File in a directory changed? (recursive)
# 20 * * * * find /var/www/ -type f -print0 | xargs -0 -r -I xxx monitor-file.sh xxx admin@example.com >> /dev/null
#
# # MySQL Slow Query log file changed?
# 24 * * * * monitor-file.sh --append-new /var/log/mysql/slow.log admin@example.com >> /dev/null
USAGE="$0 [--append-new] <full-path-of-filename> <email-addresses..>"
APPEND=0
# Set APPEND option from command line
if [ "$1" = "--append-new" ]; then
APPEND=1
shift
fi
# Get absolute path and test for existence
file=`readlink -f $1`
shift
if ! [ -f $file ]; then
echo "Not a file: $file"; echo $USAGE; exit 1
fi
tsDir=/tmp/watching`dirname $file`
timestampFile=$tsDir/`basename $file`
emails=$@
# Create the timestamp directory if it does not yet exist
if ! [ -d $tsDir ]; then
mkdir -p $tsDir || echo "Could not create $tsDir" && exit 1
fi
if ! [ -w $tsDir ]; then
echo "Timestamp directory not writable: $tsDir"; exit 1
fi
# Create the initial timestamp file if it doesn't exist
if ! [ -e $timestampFile ]; then
stat -c%s $file > $timestampFile && touch -r $file $timestampFile
echo "You will be notified when $file is modified" | mailx -s "[File Monitor] $file" $emails
echo "New file: $file"
exit 0
fi
# Compare old and new
timestamp=$(date -r $timestampFile)
nowstamp=$(date -r $file)
oldSize=$(cat $timestampFile)
newSize=$(stat -c%s $file)
bytes=$(($newSize - $oldSize))
if [ "$timestamp" == "$nowstamp" ]; then
exit 0 # no change
else
echo "Modified: $file"
echo "$file has been modified:
Old Timestamp: $timestamp
New Timestamp: $nowstamp" > $timestampFile.diff
if [ "$APPEND" -eq "0" ]; then
echo "
Old Size: $oldSize
New Size: $newSize" >> $timestampFile.diff
else
echo "" >> $timestampFile.diff
if [ "$bytes" -lt "0" ]; then
echo "File shrunk from $oldSize to $newSize bytes!" >> $timestampFile.diff
elif [ "$bytes" -eq "0" ]; then
echo "File size did not change" >> $timestampFile.diff
else
tail -c $bytes $file >> $timestampFile.diff
fi
fi
mailx -s "[File Monitor] *** ALERT *** $file" $emails < $timestampFile.diff
rm -f $timestampFile.diff
# Update file
stat -c%s $file > $timestampFile && touch -r $file $timestampFile
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment