Command output monitor

Sends you an email when the output of a Unix or Linux command has changed since the last check. You can change this source if you want. Just register and log in. Opslaan = save, Pagina aanpassen = Edit page.

#!/usr/bin/perl
# This is a script that sends you email 
# when the output of a command has changed.
# Written by Onno Zweers. 
# License: OSL <http://www.opensource.org/licenses/osl.php>
 
use warnings; # Still testing...
 
# Where are the needed executables?
$diff = 'diff';
 
# No parameters? Show help text.
if ($ARGV[1] eq "") {
  $message =  "Command Output Monitor Version 0.1, written by Onno Zweers.\n";
  $message .= "License: OSL <http://www.opensource.org/licenses/osl.php>\n\n";
  $message .= "This program notifies you when the output of a command has changed (since the last check).\n";
  $message .= "Syntax:\n";
  $message .= "  $0 \@ command [arguments]\n";
  $message .= "  $0 someone\@somewhere.com command [arguments]\n";
  $message .= "When using only a \@, the result is sent to stdout instead of email.\n";
  $message .= "You can pipe commands like this:\n";
  $message .= "  $0 \@ command_1 [arguments] \\| command_2 [arguments]\n";
  die $message;
}
 
# Read input parameters
($email_address, @commandparts) = @ARGV;
$command = join(" ", @commandparts);
 
if ($email_address eq '@') {
  $email_address = "";
}
 
# Get additional info, to use in email.
chomp($hostname = `hostname`);
 
 
# Where to store the output, for comparison later?
if ($ENV{HOME} eq "") {
  die '$ENV{HOME} not set.';
}
$basicpath = $ENV{HOME} . '/.command-output-monitor/';
`mkdir -p $basicpath`;  # The -p makes sure that the path exists!
$pathaddition = lc($command);
$pathaddition =~ s/[:|\/ ]/_/ig;  # Replace the characters :|/ with a _.
$oldfilename = $basicpath . $pathaddition;
$newfilename = $basicpath . $pathaddition . ".new";
 
# We execute the command and collect its output.
# We strip out comments, because we don't need to know
# when a comment has changed.
`$command | grep -v "^#"  1>$newfilename`;
$exit_value = $? >> 8;
if ($exit_value != 0) { die "Error executing '$command': $!"; }
 
# Is there no saved output? Then it must be the first time we check this output.
if (open (JUSTCHECKING, '<', $oldfilename)) {
  close JUSTCHECKING;
  $firsttime = "no";
} else {
  $firsttime = "yes";
}
 
# If no saved output exists, we create an empty file.
# Diff needs a file to compare with, even if it is empty.
if ($firsttime eq "yes") {
  open (OLDOUT, '>', $oldfilename) || die "Could not create $oldfilename: $!";
  close OLDOUT;
}
 
# Compare new results with saved old results
# -b = ignore difference in whitespace
# -i = ignore case
$difference = `$diff $oldfilename $newfilename`;
 
# Remove line numbers from diff output.
$difference =~ s/^(\d+)(,\d+)?d(\d+)(,\d+)?$/\nDeleted lines:/mg;
$difference =~ s/^(\d+)(,\d+)?c(\d+)(,\d+)?$/\nChanged lines:/mg;
$difference =~ s/^(\d+)(,\d+)?a(\d+)(,\d+)?$/\nAdded lines:/mg;
$difference =~ s/^> /\+ /mg;
$difference =~ s/^< /\- /mg;
 
# Different? Send email!
if ($difference ne "") {
  if ($firsttime eq "yes") {
    $message = "'$0' on $hostname has saved the following output from ";
    $message .= "\`$command\` for future comparison:";
  } else {
    $message = "'$0' on $hostname has checked the result of \`$command\`. ";
    $message .= "The result has changed since the previous check.";
  }
  $message .= "\n\n" . $difference;
  # No email address? Print to STDOUT.
  if ($email_address eq "") {
    print $message;
  } else {
    # Send via email
    $from = 'command-output-monitor@' . $hostname;
    $subject = "[$hostname] Changes in \`$command\`";
    &sendmail($email_address, $from, $subject, $message);
  }
} else {
  if ($email_address eq "") {
    print "No change in \`$command\`.\n";
  }
}
 
# Save the new output for next time.
`mv --force $newfilename $oldfilename`;
 
# Main program ends here.
 
 
 
# Defining functions.
 
# There are two functions for sending email. I suggest you 
# choose the one that works on your system.
 
sub sendmail() {
  # You can use this method if you have a sendmail-compatible 
  # mailserver, like Postfix, running on your system.
  local $mailprog = '/usr/sbin/sendmail';
  local $email_address = $_[0];
  local $from = $_[1];
  local $subject = $_[2];
  local $message = $_[3];
  open (MAIL, "|$mailprog -t >/dev/null 2>&1") || die "Could not send mail using $mailprog: $!";
  print MAIL "From: $from\n";
  print MAIL "To: $email_address\n";
  print MAIL "Subject: $subject\n";
  print MAIL "\n";
  print MAIL $message;
  print MAIL "\n";
  close(MAIL);
}
 
 
sub smtp() {  # Connect to SMTP server
  local $email_address = $_[0];
  local $from = $_[1];
  local $subject = $_[2];
  local $message = $_[3];
  &open_socket($config{'sched_smtp'}, 25, MAIL);
  &smtp_command(MAIL);
  &smtp_command(MAIL, "helo ".&get_system_hostname()."\r\n");
  &smtp_command(MAIL, "mail from: $from\r\n");
  foreach $t (split(/,/, $config{'sched_email'})) {
    &smtp_command(MAIL, "rcpt to: $t\r\n");
  }
  &smtp_command(MAIL, "data\r\n");
  print MAIL "From: $from\r\n";
  print MAIL "To: $email_address'}\r\n";
  print MAIL "Subject: $subject\r\n";
  print MAIL "\r\n";
  $message =~ s/\r//g;
  $message =~ s/\n/\r\n/g; 
  print MAIL $message;
  print MAIL "\r\n";
  &smtp_command(MAIL, ".\r\n");
  &smtp_command(MAIL, "quit\r\n");
  close(MAIL);
}
 
command_output_monitor.txt · Laatst gewijzigd: 2006/03/20 21:15
 
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
Copyright © Onno Zweers