Skip to main content

Redirect

Shell redirection operators control where a command's input comes from and where its output goes. The > operator writes stdout to a file, >> appends, < reads stdin from a file, and 2> captures stderr. Combining them allows precise control over all three standard streams.

Understanding Linux Redirection

What Is Redirection in Simple Terms

Every process has three standard streams: stdin (input), stdout (output), and stderr (errors). By default, stdin reads from the keyboard and stdout/stderr print to the terminal. Redirection changes these defaults — pointing streams at files, devices, or other commands instead.

How It Works

◈ DIAGRAM
+------------------------------------------+
| File descriptor table for any process |
| |
| 0 = stdin <- keyboard (default) |
| 1 = stdout -> terminal (default) |
| 2 = stderr -> terminal (default) |
+------------------------------------------+
Redirection changes where each FD points:
command > file.txt
FD 1 now points to file.txt instead of terminal
command 2>&1
FD 2 now points wherever FD 1 currently points

Complete redirection reference:

Bash
## Redirect stdout to file (overwrites)
command > output.txt
command 1> output.txt ## same (1 is stdout FD)
## Append stdout to file
command >> output.txt
## Redirect stderr to file
command 2> errors.txt
## Redirect stderr to stdout (combine both streams)
command 2>&1 ## order matters
command > all.txt 2>&1 ## both go to file
command &> all.txt ## shorthand for above (bash only)
## Discard stdout
command > /dev/null
## Discard all output
command > /dev/null 2>&1
command &> /dev/null ## bash shorthand
## Read stdin from file
command < input.txt
## Here-document (inline stdin)
cat << 'EOF'
line 1
line 2
EOF
## Here-string (single string as stdin)
grep pattern <<< "search in this string"
## Tee: write to file AND pass to next command
command | tee output.txt | next-command
## Tee append
command | tee -a output.txt

Practical Commands

Bash
## Log script output to file while also showing on terminal
./deploy.sh 2>&1 | tee /var/log/deploy-$(date +%Y%m%d).log
## Separate stdout and stderr logs
./build.sh > /var/log/build.log 2> /var/log/build-errors.log
## Suppress error output from a command
find / -name 'config.yaml' 2>/dev/null
## Read file line by line
while IFS= read -r line; do
echo "Processing: $line"
done < /etc/hosts
## Write to a file requiring root from a non-root script
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
## tee runs as sudo, so it can write the file
## Without tee: sudo echo ... >> /etc/sysctl.conf FAILS
## (>> is processed by the shell BEFORE sudo runs)

Troubleshooting

Symptom Command What to Check
Error output not captured Add 2>&1 Only stdout redirected, not stderr
sudo echo fails to write Use sudo tee Shell handles >> before sudo
Order of 2>&1 matters cmd 2>&1 > file vs cmd > file 2>&1 Wrong order sends stderr to terminal
Common Mistake

Writing command 2>&1 > file.txt expecting both stdout and stderr to go to the file. This is wrong. 2>&1 redirects stderr to wherever stdout currently points (the terminal), THEN > file.txt redirects stdout to the file. The correct order is command > file.txt 2>&1.

Tip

Use sudo tee when you need to write to a root-owned file from a script. echo 'content' | sudo tee /etc/protected-file works because tee runs as sudo. The alternative sudo echo 'content' >> /etc/protected-file fails — the shell processes >> before elevating to sudo.

Frequently Asked Questions

Why does `command > file 2>&1` work but `command 2>&1 > file` behave differently?

Redirection operators are processed left to right, and `2>&1` means 'duplicate file descriptor 1's current target into descriptor 2' — a snapshot, not a permanent link. In `> file 2>&1`, stdout is redirected to the file first, then stderr is pointed at wherever stdout now points (the file), so both end up in the file. In `2>&1 > file`, stderr is redirected to wherever stdout currently is (the terminal) first, then stdout is separately redirected to the file — leaving stderr still going to the terminal.

Why does `> file` silently destroy the file's previous contents, and what's the safe alternative?

The `>` operator truncates the target file to zero length before writing, with no confirmation — a classic accident is meaning to append with `echo text > log.txt` in a loop and instead wiping the log on every iteration. Use `>>` to append instead of overwrite, and if you're worried about accidentally clobbering an existing file, `set -o noclobber` in bash makes `>` fail instead of truncating unless you explicitly force it with `>|`.