You can send stdout and stderr to different destinations

Command line tools generally produce some kind of output on the screen. This output is actually two (or more) streams, and these streams can be handled independently.

The typical command output channel is called `STDOUT`. For example, when you run `ls -la` you will get a detailed directory listing on your screen/console. This listing is sent on STDOUT. But if something goes wrong and your command generates an error message, this information is sent in a different stream, called `STDERR`. By default, STDERR is handled the same way as STDOUT, and appears on the console.

If you redirect the output of a command to a text file (for example, `ls -la > listing.txt`), and your command generates an error, this error message will be recorded in the text file. But what if you don’t want to have the error message go to the same place as the command’s output?

There is a command line shorthand to refer to STDOUT and STDERR, and you can use this shorthand to choose what to do with each stream. This shorthand is called file descriptors. STDOUT’s file descriptor is 1, and STDERR’s file descriptor is 2.

Here’s where 1> and 2> come into play. Let’s say you have a command that generates both useful output and an error. For example, a directory listing for two files, one that exists, and one that doesn’t, such as ls -la realfile.txt notrealfile.txt will give you the following:

~ ls -la realfile.txt notrealfile.txt
ls: notrealfile.txt: No such file or directory
-rw-r--r--  1 staff  staff  14172 10 Sep  2017 realfile.txt

The first line is STDERR. The second line is STDOUT. What if you wanted to only get information on the file that exists, and not get an error message for the file that doesn’t exist? You do this by directing STDERR elsewhere, like this:

~ ls -la realfile.txt notrealfile.txt 2>/dev/null
-rw-r--r--  1 staff  staff  14172 10 Sep  2017 realfile.txt

By adding the 2>/dev/null, the error message (STDERR, or file descriptor 2) is redirected, in this case to /dev/null, leaving only STDOUT to appear on the screen.

You could also use STDERR redirection to log errors separately. For example, if a command is scheduled to run on a regular basis, you can append any error messages to a log file, by adding 2>>/path/to/logfile.txt. Each time the command generates an error, the error message will be added to the end of logfile.txt.

For a really good set of examples, see this Stack Overflow page. This syntax works in Linux, OSX/MacOS, and Windows. Figuring this out was a monolith-moment for me.

Leave a Reply

Your email address will not be published. Required fields are marked *