So...I have a temperature log running on a secure room at my day job. I foolishly commented out its cronjob while working on its script, and left it commented out, so I missed some data points. Ouch, mea culpa, back to the Perl drawing board. I hacked up this little script to sit in the crontab and run periodically to make a 'shell assertion' that a particular file is up to date, and to email if not. I used
Safe to provide some security for the supplied expression and also provided a little quoting for the file. If the email is left out, it just prints when it fails, and if the email is 'result', it prints what the expression evaluates to.
#!/usr/bin/perl
# script: assert
# SSF 072110 tests a perl expression (like a file test) and emails you
+ if false
# Copyright (C) 2010 Xenoscience - released under GPLv3 - All rights r
+eserved
use strict;
use warnings;
use vars qw/$cmdMail $host/;
use LWP::MediaTypes qw(guess_media_type read_media_types);
use MIME::Entity;
use Safe;
BEGIN {
$cmdMail='/usr/lib/sendmail'; # location of your sendmail
$host=`whoami`.'@'.`hostname`; # who am I
read_media_types('/etc/mime.types'); # location of your mime.types
+ file
}
sub sendmail { # returns undef or error
my ($from,$to,$subject,$body,@attachments)=@_;
my $ret;
my $top=build MIME::Entity
From => $from,
'Reply-to' => $from,
To => $to,
Subject => $subject,
Data => $body;
if (@attachments) {
for my $path (@attachments) {
my $type=guess_media_type($path);
$top->attach(
Path => $path,
Type => $type,
Encoding => '-SUGGEST'
);
}
}
$top->sync_headers(Length=>'COMPUTE') if @attachments;
if (open(MAIL,"| $cmdMail -t -i")) {
$top->print(\*MAIL);
close MAIL;
} else {
$ret="Mail to $to failed: $!";
}
$ret;
}
my ($expr,$file,$email,$msg)=@ARGV;
die "usage: assert 'expr' [file|1] [email] [message]\n" unless $expr;
$file||=1;
$expr=~s/:f:/q{$file}/g;
my $cpt=Safe->new('eval_safe'); # only one dungeon
$cpt->permit(':filesys_read');
my $value=$cpt->reval($expr);
die "eval_safe { $expr }:\n$@\n" if $@;
if ($email=~/result/i) {
my $result=defined $value ? $value : 'undef';
print "$expr evaluated to $result\n";
}
unless ($value) {
$msg||="{ $expr } is false";
if ($email=~/[@]/) {
my $err=sendmail($host,$email,'Assertion failed',$msg);
die $err if $err;
} else {
print $msg,"\n";
}
}
exit;
and the cronjob that invokes it
# ASSERTIONS - sanity checks
38 23 * * * assert '-r :f: && -M :f: < 1.0' /home/admin/www/templog/
+index.htm admin@server.com 'Check the templog!'
All comments greatly appreciated!
SSF