4 use Digest::MD5 qw(md5_hex);
8 crondiff.pl - Run command periodically and compare their output.
12 crondiff.pl is designed to be run from cron periodically. It takes as
13 input a list of commands to run. Each time it is invoked, it runs the
14 commands listed, and sends mail to the user running the script if the
15 output of that command has changed since the last run.
23 Create a file C<~/.crondiff/cmdlist>, containing one line per file, of
24 commands to be checked.
28 Add C<crondiff.pl> to your crontab. The following example runs it
29 directly out of the locker (not necessarily a good idea!) every hour:
31 # m h dom mon dow command
32 0 * * * * PATH=/bin:/usr/bin: perl /mit/snippets/crondiff/crondiff.pl
42 Mail goes to C<$USER@mit.edu>, for the user who runs this script.
46 Mail will be sent using C<mutt -x>.
50 If you don't like these assumptions, patches are welcome :)
54 my $confdir = $ENV{HOME} . "/.crondiff";
56 chomp(my $user = `id -un`);
59 my $mailto = $ENV{USER} . '@mit.edu';
60 my @mailer = qw(mutt -x);
62 my $cachedir = "$confdir/cache";
64 mkdir("$cachedir") unless -e "$cachedir";
66 open(my $clist, "<", "$confdir/cmdlist")
69 while(my $cmd = <$clist>) {
71 my $hash = md5_hex($cmd);
77 open(STDOUT, ">>", "$cachedir/$hash.new");
78 open(STDERR, ">>", "$cachedir/$hash.new");
83 # Exited with error, should send mail, but punting for now.
84 unlink("$cachedir/$hash.new");
86 } elsif(-f "$cachedir/$hash"
87 && system("diff -q $cachedir/$hash.new $cachedir/$hash > /dev/null 2>&1") != 0) {
89 if(($pid = fork) == 0) {
91 open(STDOUT, "|-", @mailer, $mailto, '-s', "Output of [$cmd]");
94 system("diff", "-u", "-U", "0", "$cachedir/$hash", "$cachedir/$hash.new");
100 rename("$cachedir/$hash.new", "$cachedir/$hash");