One of the best features of the Linux command line is the ability to efficiently direct input and output to and from files and other programs.
Every program begins with 3 open file streams.
- stdin (file descriptor 0) – input from the user, usually keyboard
- stdout (file descriptor 1) – standard output that is displayed on the screen
- stderr (file descriptor 2) – standard error output, also displayed on the screen
We can redirect the stdout from a command to a file. The file is created if it doesn’t exist and is truncated if it does.
$ command > outfile
Any error messages produced by the command will still be sent to the command line. To redirect both stdout and stderr you can do this.
$ command &> outfile
Lets say you want to suppress the error messages from a command and view only the successful output on the command line.
$ command 2> /dev/null
The error messages in this case will be sent to ‘/dev/null‘ which is a special device that discards all data sent to it.
If you want to append stdout to a file. The file is still created if it doesn’t exists.
$ command >> outfile
To append stderr to a file.
$ command 2>> outfile
Its a little more complex to append both stdout and stderr to a file.
$ command >> outfile 2>&1
Here stdout is appended to file and stderr is redirected to stdout.
If you want to redirect stdin from a file to a command.
$ command < inputfile
We can combine redirection of stdin from the inputfile and stdout to the outfile.
$ command < inputfile > outfile
A more complex example where all 3 streams are redirected.
$ command < inputfile > outfile 2>&1
So far I have only showed how to direct file streams from program to a file and vice versa. You can also redirect the output from one command to the input of another. This is one of the most powerful features of Linux, and learning to do it well will make you a better Linux user.
Lets direct the stdout from one command to the stdin of another. Chaining commands togather is done with the pipe character '|'.
$ command1 | command2
Here we "pipe" the output from command1 to command 2.
As you can imagine we can get really creative and combine all of this into a single command line statement.
$ command1 2>~/errorfile | command2 > ~/resultfile 2>> ~/errorfile
Lets go over this.
- command1 will truncate and write stderr to 'errorfile' in your home directory
- stdout is piped to the stdin of command2
- the final results from stdout of command2 are saved in 'resultfile'
- command2 stderr will be appended to 'errorfile'