Wednesday, October 10, 2012

Logging STDOUT, STDERR and outputting STDERR

You may find yourself with the need to log both STDOUT and STDERR but also display STDERR. A perfect example is when running cronjobs on Linux. As we all know getting too many notifications will result in the important notifications being lost in the noise. The solution is generally only to show errors. The problem is that those errors might lose context without various debug information. This is where I/O redirection becomes handy. Because we only want to receive emails (cron automatically sends all STD output as an email to the job owner) for errors we can use the following:

<command> 2>&1 >>blah.log | tee -a blah.log

What this does is runs <command> and copies STDERR (file descriptor 2) to STDOUT (file descriptor  1, 2>&1) and then redirects (>>) STDOUT (file descriptor 1) to blah.log.  Because of the order STDERR is not being appended to the blah.log.   That happens in the pipe to the tee command.  The tee command takes input from STDIN, adds it to a file and then echos that output to STDOUT.  The net result is that we now have STDERR from <command> being emailed to us should we use that series of commands in a cronjob.