The tee command in Linux
tee duplicates its standard input: one copy to standard output (onward down the pipeline or to your screen), one copy to each named file. It solves two everyday problems: watching a long process live while keeping a log, and — because tee is a process that can be run under sudo — writing to root-owned files from a pipeline.
How tee works
tee is deliberately trivial: read stdin, write each chunk to stdout and to every named file. No parsing, no buffering tricks. Its value is topological — it is the one standard way to give a stream two destinations, turning a pipeline from a line into a T-junction (the plumbing fitting it is named for).
The sudo idiom works because of process boundaries: in "sudo cmd > file", your unprivileged shell performs the redirection before sudo exists; in "cmd | sudo tee file", the file is opened by tee, which IS the privileged process. Same ingredients, opposite ownership of the write — a two-line lesson in who does what in a pipeline.
Syntax
CMD | tee [OPTIONS] FILE... Common options
| Option | What it does |
|---|---|
-a | Append to the files instead of overwriting. |
(multiple files) | tee a.log b.log writes both. |
- (in pipelines) | tee sits mid-pipeline: cmd | tee copy.txt | next. |
How to use tee: examples
$ ./deploy.sh 2>&1 | tee deploy-$(date +%F).log See the deploy live AND keep a timestamped record — errors included.
$ echo "127.0.0.1 dev.local" | sudo tee -a /etc/hosts THE sudo-write idiom: the privileged process (tee) performs the file write that shell redirection cannot.
$ make 2>&1 | tee build.log | grep -i error Full log saved, errors surfaced — tee in the middle of a pipeline.
Real-world use cases for tee
The auditable migration
Running a risky one-off: ./migrate.sh 2>&1 | tee migrate-$(date +%F-%H%M).log. You watch live, and the timestamped transcript exists forever — the difference between "I think it said OK" and evidence.
Branching a pipeline
Need both the full data and a summary: generate.sh | tee full.csv | wc -l writes the file AND counts records in one pass. tee mid-pipeline is the T-junction every multi-consumer flow needs.
Pro tips and common mistakes
- echo line | sudo tee -a /etc/file is THE way to append to root-owned files from a normal shell.
- tee -a for logs you accumulate; bare tee truncates like >.
- Remember 2>&1 before the pipe when errors must be in the transcript too.
Frequently asked questions about tee
Why tee for sudo writes?
In sudo cmd > file, the redirection is done by your unprivileged shell. Piping into sudo tee file moves the write into a root process. Add -a to append.
Does tee capture stderr?
Only what reaches its stdin. Merge first: cmd 2>&1 | tee log.
Related commands
Find lines matching a pattern in files or piped input — the workhorse of text search.
echoPrint text and variables, and write or append to files with > and >>.
sudo & suTemporary privilege, audited — and why sudo won everywhere.