From: Simon Ruderich Date: Fri, 14 Mar 2014 14:35:55 +0000 (+0100) Subject: bin/chronic: add, patched chronic with -l option X-Git-Url: https://ruderich.org/simon/gitweb/?a=commitdiff_plain;h=ff2dd9300494828ddbb27335a59b2752391c4e00;p=config%2Fdotfiles.git bin/chronic: add, patched chronic with -l option --- diff --git a/bin/chronic b/bin/chronic new file mode 100755 index 0000000..a9fa47b --- /dev/null +++ b/bin/chronic @@ -0,0 +1,84 @@ +#!/usr/bin/perl + +=head1 NAME + +chronic - runs a command quietly unless it fails + +=head1 SYNOPSIS + +chronic COMMAND... + +=head1 DESCRIPTION + +chronic runs a command, and arranges for its standard out and standard +error to only be displayed if the command fails (exits nonzero or crashes). +If the command succeeds, any extraneous output will be hidden. + +A common use for chronic is for running a cron job. Rather than +trying to keep the command quiet, and having to deal with mails containing +accidental output when it succeeds, and not verbose enough output when it +fails, you can just run it verbosely always, and use chronic to hide +the successful output. + + 0 1 * * * chronic backup # instead of backup >/dev/null 2>&1 + +=head1 AUTHOR + +Copyright 2010 by Joey Hess + +Original concept and "chronic" name by Chuck Houpt. + +Licensed under the GNU GPL version 2 or higher. + +=cut + +use warnings; +use strict; +use IPC::Run qw( start pump finish timeout ); + +if (! @ARGV) { + die "usage: chronic [-l LOGFILE] COMMAND...\n"; +} + +my $logfile; +if (@ARGV >= 3 and $ARGV[0] eq '-l') { + $logfile = $ARGV[1]; + shift @ARGV; + shift @ARGV; +} + +my ($out, $err); +my $h = IPC::Run::start \@ARGV, \*STDIN, \$out, \$err; +$h->finish; +my $ret=$h->full_result; + +if (defined $logfile) { + open my $fh, '>', $logfile + or showout_and_die("failed to open logfile '$logfile'"); + print $fh $err; # stderr is more interesting, show it first + print $fh $out; + close $fh + or showout_and_die("failed to close logfile '$logfile'"); +} + +if ($ret >> 8) { # child failed + showout(); + exit ($ret >> 8); +} +elsif ($ret != 0) { # child killed by signal + showout(); + exit 1; +} +else { + exit 0; +} + +sub showout { + print STDOUT $out; + print STDERR $err; +} +sub showout_and_die { + my $errno = $!; + showout(); + die "chronic: $_[0]: $errno\n"; +}