Terminal · intermediate
Splitting output with tee
tee copies bytes from standard input to standard output and simultaneously writes copies to one or more files.
Why it matters
It preserves a live pipeline while recording or observing intermediate data that would otherwise require rerunning an expensive producer.
Mental model
How to reason about splitting output with tee
For each block read from stdin, write the same bytes to every named file and to stdout; downstream processing continues from that stdout copy.
Analogy
It is a plumbing T-junction that sends the same flow onward while filling a side reservoir for inspection or storage.
Examples
See the boundary, not just the happy path
Worked example · Record an intermediate stream
curl -fsS "$URL" | tee response.json | jq '.items | length'The exact response bytes are saved to response.json and also continue to jq, avoiding a second network request.
Worked example · Append to a log
run_checks 2>&1 | tee -a checks.logThe shell combines stderr with stdout before the pipe, and tee -a appends the combined stream while still displaying it.
Useful contrast · Redirection ends the branch
generate > output.txtPlain redirection sends stdout only to the file; tee is needed when the same bytes must also remain available on stdout.
Common mistakes
Misconceptions to remove early
Forgetting that tee replaces files by default
Use -a only when appending is intended; otherwise each named output file is opened for overwrite.
Assuming tee captures stderr automatically
A pipe receives stdout by default, so stderr must be deliberately combined or separately handled before tee can copy it.
Quick check
Can you predict the result?
1. What two destinations does tee output.txt write to by default?
- • output.txt and standard output
- • output.txt and standard error
- • Only output.txt
2. Why does command | tee log not normally capture command's stderr?
Keep building