I decided to write a script that could approximate a solution to the question of only emailing on stderr output.
The key is storing stdout/stderr to files until stderr is detected and then outputting the combined file.
The combined file can loosely be said to retain stdout/stderr order in so far as tail can iterate over its files quickly enough. If there's no buffering and a command takes more than a second or two and there's some delay between stdout/stderr ouputs then this approach can approximate ordered stdout/stderr output.
I call this script cron-wrapper.sh. It's purpose is to accept a command and arguments and run them.
It's intended to be called from a crontab like this:
30 * * * * root sh cron-wrapper.sh sh cron-job.sh >/dev/null
Note that when outputing everything on stderr "everything" is output to stderr not stdout to fulfill my requirement that cron email everything on stderr output
Script:
#!/bin/bash # Input cmd=$1 shift # Run given command in background so we can tail output files immediately stdoutFile=`mktemp` stderrFile=`mktemp` $cmd "${@}" >"$stdoutFile" 2>"$stderrFile" & cmdPid=$! # Tail stdout and stderr files teeFile=`mktemp` tail -F -s 0.01 --pid=$cmdPid --quiet --silent "$stdoutFile" "$stderrFile" | tee "$teeFile" # Output everything if stderr output detected if [ -s "$stderrFile" ]; then cat "$teeFile" >&2 fi # Clean up rm -f "$stdoutFile" "$stderrFile" "$teeFile"
teein.