]> snippets.scripts.mit.edu Git - Scripts/git/.git/blame - crondiff/crondiff.pl
kdo: Upstream krb5 now supports kswitch
[Scripts/git/.git] / crondiff / crondiff.pl
CommitLineData
b0e0b6e8
NE
1#!/usr/bin/env perl
2use strict;
3use warnings;
4use Digest::MD5 qw(md5_hex);
5
6=head1 NAME
7
8crondiff.pl - Run command periodically and compare their output.
9
10=head1 DESCRIPTION
11
12crondiff.pl is designed to be run from cron periodically. It takes as
13input a list of commands to run. Each time it is invoked, it runs the
14commands listed, and sends mail to the user running the script if the
15output of that command has changed since the last run.
16
17=head1 USAGE
18
19=over 4
20
21=item
22
23Create a file C<~/.crondiff/cmdlist>, containing one line per file, of
24commands to be checked.
25
26=item
27
28Add C<crondiff.pl> to your crontab. The following example runs it
29directly out of the locker (not necessarily a good idea!) every hour:
30
31 # m h dom mon dow command
32 0 * * * * PATH=/bin:/usr/bin: perl /mit/snippets/crondiff/crondiff.pl
33
34=back
35
36=head1 ASSUMPTIONS
37
38=over 4
39
40=item
41
42Mail goes to C<$USER@mit.edu>, for the user who runs this script.
43
44=item
45
46Mail will be sent using C<mutt -x>.
47
48=back
49
50If you don't like these assumptions, patches are welcome :)
51
52=cut
53
54my $confdir = $ENV{HOME} . "/.crondiff";
55unless($ENV{USER}) {
56 chomp(my $user = `id -un`);
57 $ENV{USER} = $user;
58};
59my $mailto = $ENV{USER} . '@mit.edu';
60my @mailer = qw(mutt -x);
61
62my $cachedir = "$confdir/cache";
63
64mkdir("$cachedir") unless -e "$cachedir";
65
66open(my $clist, "<", "$confdir/cmdlist")
67 or exit;
68
69while(my $cmd = <$clist>) {
70 chomp($cmd);
71 my $hash = md5_hex($cmd);
72 my $pid = fork;
73 if($pid == 0) {
74 # Child
75 close(STDOUT);
76 close(STDERR);
77 open(STDOUT, ">>", "$cachedir/$hash.new");
78 open(STDERR, ">>", "$cachedir/$hash.new");
79 exec($cmd);
80 }
81 waitpid($pid, 0);
82 if($? != 0) {
83 # Exited with error, should send mail, but punting for now.
84 unlink("$cachedir/$hash.new");
85 next;
86 } elsif(-f "$cachedir/$hash"
87 && system("diff -q $cachedir/$hash.new $cachedir/$hash > /dev/null 2>&1") != 0) {
88 # Output changed
89 if(($pid = fork) == 0) {
90 close(STDOUT);
91 open(STDOUT, "|-", @mailer, $mailto, '-s', "Output of [$cmd]");
92 system("date");
93 print "----\n";
94 system("diff", "-u", "-U", "0", "$cachedir/$hash", "$cachedir/$hash.new");
95 exit;
96 } else {
97 waitpid($pid, 0);
98 }
99 }
100 rename("$cachedir/$hash.new", "$cachedir/$hash");
101}