The Linux tee Command: Write Output to a File and stdout at the Same Time
What tee Does
tee sits in a pipeline, reads stdin, and writes it simultaneously to both stdout and one or more files. The name comes from a T-junction in plumbing: data flows in one side and splits into two identical streams. Without tee, redirecting with > would consume the stream and leave nothing for downstream commands.
flowchart LR
stdin["stdin<br/>from pipe"] --> tee["tee"]
tee --> stdout["stdout<br/>(terminal / next command)"]
tee --> file["file<br/>(saved to disk)"]
Basic Syntax and the -a Flag
The minimal invocation is command | tee filename. By default tee overwrites the target file (like >). Add -a to append instead (like >>):
$ echo "first line" | tee log.txt
first line
$ echo "second line" | tee -a log.txt
second line
$ cat log.txt
first line
second line
Silencing stdout and Pipeline Use
tee always writes to stdout. To suppress it, redirect to /dev/null: command | tee file > /dev/null. The file is still written; the terminal stays quiet.
You can also place tee between two commands to save intermediate results while the pipeline continues, invaluable for debugging:
$ cat /etc/hostname | tee saved-hostname.txt | wc -c
5
$ cat saved-hostname.txt
arch
flowchart LR
cat["cat /etc/hostname"] --> tee["tee saved-hostname.txt"]
tee --> wc["wc -c"]
tee --> file["saved-hostname.txt"]
Writing to Multiple Files and Common Pitfalls
tee accepts multiple filename arguments, writing identical copies to all of them: echo "server=localhost" | tee config-a.conf config-b.conf.
A common mistake is writing command | tee > file. The > redirect applies to tee’s stdout, not its file-writing behavior, tee with no filename just passes stdin through unchanged. The correct form is command | tee file.
When to Reach for tee
Three canonical use cases: (1) watching a long command’s progress while keeping a log; (2) debugging a multi-stage pipeline by inspecting intermediate data; (3) writing the same output to several files in one shot. If you only need the file and do not care about seeing output, plain > is simpler.