supuner

Overview

supuner (SUPpress UNless ERror) executes a command and manipulates its stderr and stdout, allowing the user control over when they are displayed and / or outputted. It has two chief uses:

  • Suppressing all output from a command unless there is an error, in which case the combined output of stderr and stdout is sent to stderr. This is useful for `chatty' scripts in cron jobs: if they run successfully, receiving an e-mail from them is distracting.
  • For long-running processes (e.g. database processing jobs running inside screen / tmux), sending output to both the console and a log-file. If an error occurs, the log file can then be e-mailed to an appropriate person.

Download

supuner is part of my bin repository; you can track supuner's evolution via git.

Usage

The command-line arguments are as follows:
supuner [-e] [-o <filename>] <command>
Where:
-eBy default sunuper suppresses all output to stderr and stdout unless an error occurs in which case a combined copy of stderr and stdout is sent to stderr. With the -e (`echo') switch, the command's normal stdout and stderr are sent to the console. This allows one to both interactively view and log a commands output simultaneously.
-o <filename>is a file to store combined stderr / stdout output. Can be combined with -q if desired.
<command>is the program, plus arguments, for execution.
supuner exits with the exit code of command.

Basic examples

Here are examples of the basic styles of use of supuner:

$ supuner ls /bin/sh                                                           
$ supuner ls /bin/sh /doesntexist
ls: /doesntexist: No such file or directory
/bin/sh
$ supuner -e ls /bin/sh                
/bin/sh
$ echo $?
0
$ supuner -e ls /bin/sh /doesntexist
ls: /doesntexist: No such file or directory
/bin/sh
$ echo $?
1
$ supuner -o /tmp/o -e ls /bin/sh /doesntexist  
ls: /doesntexist: No such file or directory
/bin/sh
$ cat /tmp/o                                                                   
ls: /doesntexist: No such file or directory
/bin/sh
$
Taking this, we can then do some more useful things. For example, we can run a command, see its output in the console, and log that to a file; if the command fails, we can then e-mail the relevant person with the copy of the log:
$ supuner -o /tmp/o -e ls /bin/sh /doesntexist \
  || mail -s "Error from ls" somebody@something.com < /tmp/o
ls: /doesntexist: No such file or directory
/bin/sh
$
If we want to do the same thing but without sending any output at all to the console we can do the following:
$ supuner -o /tmp/o ls /bin/sh /doesntexist >2 /dev/null \
  || mail -s "Error from ls" somebody@something.com < /tmp/o

Use inside screen / tmux

On one machine I run, there is a command (let's call it cmd) running in an infinite loop which prints to stdout. It runs inside a tmux so that I can login and see its current progress. However, if cmd throws an error, I want to be e-mailed about it immediately. I start tmux with a simple script which loops and calls cmd repeatedly:
$ tmux new-session -d looper.sh
The looper.sh script looks roughly like:
t=`mktemp`
while [ 1 ]; do
  supuner -e -o $t cmd || cat $t | mail -s "Error from cmd" laurie@tratt.net
done