wrapForCron

cron で動かそうとする script が,標準出力/エラー出力 に出力すると,いちいちメールが来てうるさい.しかし,コマンドが失敗したときにはやはりメールがほしい.ということで,exit status が 0でないときだけ,出力を行うようなwrapperを書いた.

#!/usr/bin/perl

#
# wrapForCron: execute the argument as a command, with closed stdout and stderr.
#    If the return code of the command is non-zero, then the output to the stdout
#    and stderr are printed to STDERR.
#

use strict;
use warnings;
use File::Temp qw/tempfile tempdir/;

my ($tfh, $tmpfile) = tempfile();
defined($tfh) && defined($tmpfile)
  or die "Failed to make temporary file: $!\n";
close($tfh)
  or die "Failed to close temporary file handle: $!\n";

# print STDERR "tempfile is ", $tmpfile, "\n";
# print STDERR join(" ", @ARGV), "\n";

open my $oldout, ">&STDOUT"
  or die "Can't dup STDOUT: $!";
open my $olderr, ">&STDERR"
  or die "Can't dup STDERR: $!";
open STDOUT, '>', $tmpfile
  or die "Can't redirect STDOUT: $!";
open STDERR, ">&STDOUT"
  or die "Can't dup STDOUT: $!";
select STDERR; $| = 1;      # make unbuffered
select STDOUT; $| = 1;      # make unbuffered

my $rc = system(@ARGV);
if ($rc != 0) {
  open STDOUT, ">&", $oldout
    or die "Can't dup OLDOUT: $!";
  open STDERR, ">&", $olderr
    or die "Can't dup OLDERR: $!";
  open(E, $tmpfile)
    or die "Failed to read-open $tmpfile: \n";
  while (<E>) {
    print STDERR;
  }
}
unlink($tmpfile)
  or die "Failed to unlink $tmpfile: $!\n";
exit $rc;