>This article was originally written by Tillman Hodgson. The most current version of it (and the copyright notice) can be found on his site.
Note that everything in this section applies to the bash shell; other shells may not have as
many or the even the same features. Even though standard input/output redirection is a basic feature
of any Unix derivative, the syntax does depend on the shell that you're using.
There are all sorts of redirection symbols that you can use. Here's a quick table of the common
ones:
- Normal:
- binary > file (send stdout to file)
- binary 2> file (send stderr to file)
- binary > file 2>&1 (send stdout and stderr to file)
- binary < file (take stdin from file)
- Append:
- binary >> file (send stdout to end of file)
- binary 2>> file (send stderr to end of file)
- binary >> file 2>&1 (send stdout and stderr to end of file)
- binary <<x (take stdin until "x" occurs)
- Pipes:
- binary1 | binary2 (pipe stdout of binary1 to stdin of binary2)
- binary1 2>&1 | binary2 (pipe stdout and stderr of binary1 to binary2)
The problem with cats ...
Take a simple redirection example such as this:cat file1 | tr -d '\015' > file2
You've wasted a process on cat, since you could accomplish the same thing (and have it execute faster!) by doing this:
tr -d '\015' < file1 > file2
Sending stderr through a pipe
Sending only stderr down a pipe, while having stdout still go to the screen, is an interesting trick. It can be done by passing the stdout and stderr file descriptors to temporary file descriptors, and basically playing a game of 3 card monte with the values:(binary 3>&1 1>&2 2>&3 3>&-) | mail me@somewhere.org &
This runs the program called "binary" and mails the errors to me@somewhere.org, while leaving the regular stdout output going to the screen. If you can follow this, you didn't need to read this document ;-)
Splitting output
If you run your output through a program called tee (usually found at /usr/bin/tee), you can split your stdout stream. This can be very useful if you want to save the output of a command to a file, but you also want to view it on the screen. For example:binary | tee results.file | lpr
takes the results of the command named "binary" and saves the stdout to ta file called "results.file" as well sending the stdout to be printed.
Why is it > somefile 2>&1 rather than 2>&1 > somefile?
The command cat file1 2>&1 >file2 results in an error message, yet cat file1 > file2 2>&1 works. This seems rather odd at first.Whats happening is that the shell is reading the commands from left to right. The reason the first command fails is that bash sees the 2>&1 first. It thinks, "Ok, I'll send the stderr to the same place and stdout", which has no effect because they're both already going to the terminal. Then the > redirects stdout to file2, but stderr is still going to the terminal. In the second example, if you read it strictly from left to right, you'll see that it makes more sense.