Standard Error & Exit Codes

The Discontents of Error Messaging

I mentioned stderr earlier, but I glossed over its actual function.

There are some problems with pipelines. One is that if you stream all the output of a command down a pipe to other commands, and part of that output is an error message, you may never discover that a command reported an error at all.

Another is that lots of things that might look like an error message could be perfectly valid output. Consider, for example, working with a log file containing the string "ERROR" on some line.

Unix systems have, for a long time, dealt with these problems by exposing a third standard stream. Programs print error messages and diagnostics to standard error, which (usually) shows up in your terminal even if you've redirected standard output elsewhere.

You can redirect stderr like you can stdout (and knowing this will come in handy sometimes), but the syntax is kind of fiddly and weird, and you shouldn't feel guilty if you have to look it up every time (or at least I don't):

Redirect stderr (file descriptor 2) to a file

command 2> filename

Redirect standard stderr (file descriptor 2) to stdout (file descriptor 1) and pipe both to another commmand

command 2>&1 | other_command

For a concise and well-researched breakdown of the problem, check out Jesse Storimer's When to use STDERR instead of STDOUT.

Exit Status

As if multiple output streams didn't make for enough extra complexity, there's another way commands signal error conditions: Every command actually has a numeric exit status, ranging from 0 to 255, where anything other than 0 signals a failure.

In Bash, you can check the most recent exit status by inspecting the special variable $?.

Exit statuses don't come up directly all that often in interactive use of the shell, but they become interesting once you start writing shell scripts. We won't get into scripting just now, but if you want to jump right in at the deep end, have a look at Mendel Cooper's Advanced Bash-Scripting Guide.

This guide was first published on Feb 17, 2015. It was last updated on Feb 17, 2015. This page (Standard Error & Exit Codes) was last updated on May 20, 2019.