Here’s a Unix shell lesson I always forget. Shell commands can send output to two places, standard output and standard error. The two are separated so that if you’re redirecting the output of the command to a file or piping it to another command, error messages generated by the command aren’t included with the expected output of the command.

This becomes a problem when you want to capture STDERR in a file, or pipe it to a command like grep so that you can search for specific things in the errors.

Fortunately, there’s a way to do this:

$ my_command 2>&1 | grep "somestring" 

The magic here is 2>&1. It means, “Redirect stream 2 to stream 1.” In Bourne shell derivatives (like bash, zsh, and ksh), stream 2 is STDERR and stream 1 is STDOUT. Once the streams are merged, you can do whatever you want with the single output stream, like pipe it to grep or redirect it to a file.

One common construct you’ll see in cron jobs is this:

1 0 * * *  run_some_script.sh > /dev/null 2>&1

Cron helpfully sends an email to the user that owns the cron job whenever the command cron is running produces any output. Putting the merged redirect to /dev/null in there sends both STDERR and STDOUT to the bit bucket so that no email is generated. Of course that also means that cron is eating the error messages, so if something goes wrong you won’t be notified in the traditional way.