Get the Most Out of Your Open-Source Software With Redirection in Bash

It took me ages to learn bash redirection properly, and I still have to concentrate sometimes to keep my &s and my >s straight. Here's the lowdown in case you, too, have intermittent brain failure on this one.

Tip of the Trade: Bash redirection is tricky. Here's a handy cheat sheet for this open-source software utility.

Bash has three standard file descriptors: stdin, stdout and stderr, which refer respectively to input, output and error output. By default, all of these are directed to the terminal, so all input comes from the terminal, and all output (regular and error) will go to the terminal.

You're probably already familiar with redirecting stdin and stdout:

process.pl < datain.txt > dataout.txt

To redirect stderr, you must be more specific:

/etc/init.d/apache2 2> errors.txt

Often, you want to redirect both stdout and stderr to the same file, and there are two ways of doing that:

rsync /home/juliet/backup juliet@server.example.com:backup 1>&2 > output.txt
The 1 refers to stdout, and the &2 to stderr (compare 2> above; here, 2 without an &, would refer to a file named 2), so stdout is redirected to stderr. stderr, which now also contains stdout, is then redirected to output.txt.

The other option is to do the same thing the other way around:

rsync /home/juliet/backup juliet@server.example.com:backup 2>&1 > output.txt
This would redirect stderr to stdout, and then the whole lot to output.txt. The main advantage to this is that, as a rule, stderr text is not kept in the buffer. Thus, if running it through less, instead of dumping it in a file, you can't page backward. By redirecting it to stdout, all the output will be kept.

Finally, you can direct both outputs straight to a file:

grep username * &> allout.txt

Correction (as of 3/18/2010)

EDIT: Sorry, I screwed up here! Thanks to those who've helpfully provided a correction.

rsync /home/juliet/backup juliet@server.example.com:backup 1>&2 

does redirect stdout to stderr (and replacing 1>&2 with 2>&1 redirects stderr to stdout). However, if you want the output to go to a file, you have to do that *before* the redirection:

rsync /home/juliet/backup juliet@server.example.com:backup 2>output.txt 1>&2 rsync /home/juliet/backup juliet@server.example.com:backup >output.txt 2>&1 

(A note on buffering: as far as the stdio library is concerned, stderr is unbuffered, while stdout is line-buffered when pointing to a terminal; so output may happen in the 'wrong' order when you mix them. However, this won't in fact affect the way that programs like less deal with the output.)

Many thanks to those who provided corrections.

Juliet Kemp has been messing around with Linux systems, for financial reward and otherwise, for about a decade. She is also the author of "Linux System Administration Recipes: A Problem-Solution Approach" (Apress, 2009).

Follow ServerWatch on Twitter

This article was originally published on Mar 15, 2010
Page 1 of 1

Thanks for your registration, follow us on our social networks to keep up-to-date