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
+------------------------------------------+| 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 pointsComplete redirection reference:
## Redirect stdout to file (overwrites)command > output.txtcommand 1> output.txt ## same (1 is stdout FD) ## Append stdout to filecommand >> output.txt ## Redirect stderr to filecommand 2> errors.txt ## Redirect stderr to stdout (combine both streams)command 2>&1 ## order matterscommand > all.txt 2>&1 ## both go to filecommand &> all.txt ## shorthand for above (bash only) ## Discard stdoutcommand > /dev/null ## Discard all outputcommand > /dev/null 2>&1command &> /dev/null ## bash shorthand ## Read stdin from filecommand < input.txt ## Here-document (inline stdin)cat << 'EOF'line 1line 2EOF ## Here-string (single string as stdin)grep pattern <<< "search in this string" ## Tee: write to file AND pass to next commandcommand | tee output.txt | next-command ## Tee appendcommand | tee -a output.txtPractical Commands
## 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 commandfind / -name 'config.yaml' 2>/dev/null ## Read file line by linewhile IFS= read -r line; do echo "Processing: $line"done < /etc/hosts ## Write to a file requiring root from a non-root scriptecho '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 MistakeWriting
command 2>&1 > file.txtexpecting both stdout and stderr to go to the file. This is wrong.2>&1redirects stderr to wherever stdout currently points (the terminal), THEN> file.txtredirects stdout to the file. The correct order iscommand > file.txt 2>&1.
TipUse
sudo teewhen you need to write to a root-owned file from a script.echo 'content' | sudo tee /etc/protected-fileworks becauseteeruns as sudo. The alternativesudo echo 'content' >> /etc/protected-filefails — 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 `>|`.