The Three Streams
Every Linux program has three standard streams. Understanding them unlocks the power of piping and redirection.
The Three Streams
| Stream | Number | Purpose |
|---|---|---|
| stdin | 0 | Standard input - where data comes in |
| stdout | 1 | Standard output - where results go |
| stderr | 2 | Standard error - where errors go |
Think of them as:
- stdin = your keyboard (by default)
- stdout = your screen (by default)
- stderr = also your screen (by default)
┌─────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ stdin │ ───→ │ COMMAND │ ───→ │ stdout │ │
│ │ (0) │ │ │ │ (1) │ │
│ │ keyboard │ │ ls, grep, │ │ screen │ │
│ └──────────┘ │ cat, etc. │ └──────────┘ │
│ │ │ │
│ │ │ ───→ ┌──────────┐ │
│ │ │ │ stderr │ │
│ └─────────────┘ │ (2) │ │
│ │ screen │ │
│ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
By default, all three are connected to your terminal. Redirection changes where they go.
stdout - Standard Output
Normal output from commands:
This is stdout - the successful result.
stderr - Standard Error
Error messages go to stderr:
Both appear on screen, but they're separate streams.
Why Separate Streams?
Because you might want to:
- Save output to a file but see errors on screen
- Discard errors but keep output
- Log errors separately from results
stdin - Standard Input
Commands can read from stdin:
When you type and press Enter, cat reads from stdin and writes to stdout.
Demonstrating the Difference
Here:
Documents:list goes to stdout- Error message goes to stderr
Both appear on screen, but they traveled different paths.
File Descriptors
Those numbers (0, 1, 2) are file descriptors. You'll use them for redirection:
# Redirect stdout (1) to file
command > output.txt
command 1> output.txt # Same thing
# Redirect stderr (2) to file
command 2> errors.txt
# Redirect both
command > output.txt 2> errors.txt
Why This Matters
Consider this script running in production:
./backup.sh > backup.log 2> errors.log
- Normal progress messages →
backup.log - Any errors →
errors.log
You can check errors.log to see if anything went wrong, without wading through thousands of success messages.
Redirecting stderr to stdout
Sometimes you want both in the same place:
command > all.log 2>&1
2>&1 means "send stderr (2) to wherever stdout (1) is going."
Order Matters
command > file 2>&1 # Correct - stderr follows stdout to file
command 2>&1 > file # Wrong - stderr goes to terminal, stdout to file
The order is crucial.
Modern Syntax
Bash 4+ has a shortcut:
command &> all.log # Both stdout and stderr to file
If you want to save command output but see errors on screen, what would you use?
Key Takeaways
- Every command has 3 streams: stdin (0), stdout (1), stderr (2)
- By default, both stdout and stderr display on screen
- They're separate so you can handle them differently
- File descriptors (0, 1, 2) let you redirect each stream
2>&1sends stderr to wherever stdout is going- Understanding streams is crucial for scripting and automation
Next: redirecting output to files.