sh I/O redirection short reference

Modified from the dash man page

The [n] is an optional number, as in ‘3’ (not ‘[3]’), that refers to a file descriptor.

           [n]> file   Redirect standard output (or n) to file.

           [n]>> file  Append standard output (or n) to file.

           [n]< file   Redirect standard input (or n) from file.

           [n1]<&n2    Duplicate n2 to standard input (or n1).

           [n]<&-      Close standard input (or n).

           [n1]>&n2    Duplicate n2 to standard output (or n1).

           [n]>&-      Close standard output (or n).

bash has all of these operators and more.

Default file descriptors

0 standard input
1 standard output
2 standard error

File descriptors 3 through 9 are empty by default, but 5 can cause some trouble. These empty file descriptors may be used to temporarily copy one of the default file descriptors. One use of a copy is to redirect standard output to a file temporarily and then back to the terminal (example).

Example: duplicate standard output into file descriptor 2, so that errors are written to the standard output.

make 2>&1 | grep Error

or

make 2<&1 | grep Error

Why do both of these work? Look at some more examples.

Inline or exec redirects

dash and bash both provide at least two syntaxes for manipulating file descriptors.

Example: echo one, two, three into the file numbers.txt

Child processes inherit open file descriptors

The exec example hints at the fact that Child processes inherit open file descriptors (TLDP). To further explore this concept let's try the redirection again, but accidentally leave out exec:

Temporary redirections

Redirecting output first to a file and then back to the terminal can be done using either inline or exec redirects:

Shorthand for stdin and stdout

All of the examples on this page up to this point have explicitly provided both sides of every redirection. This might lead to some confusion because the shorthand forms of redirection are more common. Consider again the first example:

echo "one, two, three" 1> numbers.txt

A more common way to write this would be…

echo "one, two, three" > numbers.txt

The 1 may be omitted because > redirects fd 1 by default.

Similarly, the contents of a file could be read as stdin by writing…

cat 0< numbers.txt

…but the more common form would be…

cat < numbers.txt

…where file descriptor 0 is implicit.

Links

TLDP on I/O redirection
tldp.org has an I/O redirection chapter. The subsection on using exec is particularly helpful.
GNU C library manual
One way to get familiar with sh redirection is to implement it again using C library calls. Maybe do something like: open a pipe, fork a child process, duplicate (dup2) file descriptors as needed and close unused file descriptors, execute (execv) a program in the child process, write bytes through the pipe to the child process from the parent process, and close any remaining unneeded file descriptors.
Some tricky things about redirections (this site)

Found a mistake?

Submit a comment or correction

Updates

2013 Jan 08 Comments link and errors to stdout example
2012 Aug 15 some rewordings
2011 Sep 11 markup corrections
2011 Apr 28 link to GNU libc manual. reword the dash man page excerpt.
2011 Jan 25 another way to get back to the terminal: the terminal's /dev filename
2010 Dec 15 posted