Input/output redirection is the shell mechanism that changes where a command reads input from and where it writes output to, by reassigning its file descriptors to files or to other descriptors before the command starts. In Linux shells such as Bash and Zsh, redirection operators like >, >>, < and 2> let a user save output to a file, feed a file into a program or separate error messages from normal results.
Redirection works on the three standard streams that every process inherits: standard input, standard output and standard error. It is closely related to the pipe, which connects the output of one command to the input of another, but redirection connects streams to files and descriptors rather than to other processes.
How redirection works with file descriptors
Every Unix process holds a table of file descriptors, small integers that refer to open files, terminals, pipes or sockets. By convention, descriptor 0 is standard input, 1 is standard output and 2 is standard error. A program simply reads from 0 and writes to 1 and 2, without knowing what those descriptors point to.
When the shell sees a redirection operator, it opens the target file and duplicates the descriptor before executing the command, using system calls such as open and dup2. The command then runs unchanged, but its output lands in a file instead of the terminal. This is why redirection works with any program, including ones written long before the feature was designed.
| Stream | Descriptor | Default target | Typical content |
|---|---|---|---|
| Standard input | 0 | Keyboard via the terminal | Data to be processed |
| Standard output | 1 | Terminal screen | Normal results |
| Standard error | 2 | Terminal screen | Error and diagnostic messages |
Redirection operators and their effects
Bash and other POSIX-compatible shells share a core set of portable operators, and Bash adds several convenient extensions such as &> and here strings. Scripts that must run under /bin/sh on minimal systems should stick to the POSIX operators only. The table lists the operators used in everyday work.
| Operator | Effect | Example |
|---|---|---|
> | Write standard output to a file, truncating it | ls > files.txt |
>> | Append standard output to a file | date >> run.log |
< | Read standard input from a file | sort < names.txt |
2> | Write standard error to a file | find / -name x 2> errors.txt |
2>&1 | Send standard error wherever standard output goes | make > build.log 2>&1 |
&> | Bash shorthand for both streams to one file | backup.sh &> backup.log |
<< EOF | Here document: inline multi-line input | Feeding a configuration block to a command |
<<< text | Here string: one string as input | bc <<< 2+3 |
>| | Overwrite even when noclobber is set | echo x >| file.txt |
The special file /dev/null discards everything written to it, so command > /dev/null 2>&1 silences a command completely, a pattern common in cron jobs and scripts that only care about exit codes.
Why the order of redirections matters
The shell processes redirections from left to right, and each n>&m copies the target that descriptor m has at that moment. This rule explains the most famous redirection mistake in shell scripting.
| Command | Where standard output goes | Where standard error goes |
|---|---|---|
cmd > out.log 2>&1 | out.log | out.log |
cmd 2>&1 > out.log | out.log | The terminal, where stdout pointed before |
cmd 2> err.log > out.log | out.log | err.log |
cmd 2>&1 | tee out.log | Pipe to tee, then terminal and file | Pipe to tee, then terminal and file |
In the second command, standard error is duplicated to the terminal first, and only afterwards is standard output moved to the file. Writing file redirection first, then `2>&1` is the correct and portable pattern for capturing both streams.
Redirection compared with pipes and related tools
Redirection, pipes and a few helper tools solve related problems in the shell & terminal environment, and choosing the right one keeps commands simple.
| Mechanism | Connects | Typical use |
|---|---|---|
| Redirection | A stream to a file or descriptor | Saving logs, reading input files |
| Pipe | Output of one process to input of another | Chaining grep, sed and awk |
| tee | One input to a file and standard output | Logging while still viewing output |
| Process substitution | Command output presented as a file name | diff on the output of two commands |
| Command substitution | Command output inserted into a command line | Storing a result in a variable |
A common inefficiency is the useless use of cat, as in cat file | grep x. Redirection or a file argument, as in grep x < file, avoids an extra process, although the difference matters mainly in loops and large scripts.
Pitfalls and safe practices
- Truncating the input file:
sort file > fileempties the file before sort reads it; write to a temporary file and move it instead. - Accidental overwrites: enabling
set -o noclobbermakes>refuse to overwrite existing files. - Redirection and sudo: in
sudo echo x > /etc/file, the redirection runs in the unprivileged shell;echo x | sudo tee /etc/fileworks. - Lost error messages: redirecting only standard output hides failures that appear on standard error in logs.
- Buffering surprises: output to a file or pipe is block-buffered, so log lines can appear late compared with terminal output.
Scripts that run unattended should capture both streams explicitly and check exit codes, because redirection changes where messages go but not whether a command succeeded.
The simple explanation
Every command in a terminal has an input channel and two output channels. By default, input comes from the keyboard, and output appears on the screen.
Redirection is like re-routing the plumbing. Instead of showing results on the screen, a command can pour them into a file. Instead of waiting for typing, it can read from a file. Error messages can go to a separate file, so they do not mix with the useful results.
How it is used in practice
A system administrator schedules a nightly database backup script through cron on a Linux server. Without redirection, any output would be lost or mailed unpredictably, and failures could go unnoticed for days.
The crontab line runs backup.sh >> /var/log/backup.log 2>&1, which appends both normal output and errors to one log with a timestamp printed by the script. A separate monitoring check reads the last lines of the log each morning. One night the disk fills up, and the error message from standard error appears in the log rather than vanishing, so the administrator finds and fixes the problem within an hour of starting work instead of discovering it during a restore.