Getting Started with tee - Splitting Command Output
What You'll Learn
- What
teeis and why it's named after a T-shaped pipe fitting - How to display and save command output simultaneously with
command | tee file - How the
-aflag appends instead of overwrites - How to write output to multiple files at once
- The
sudo teepattern for writing to root-owned files safely
What is tee?
Conclusion:
teesends output to screen and file at once — watch and record simultaneously.
|) to chain commands, but I want to save the intermediate results too. Is there a way to do that?tee is for! Think of it like a T-shaped pipe fitting — it splits the output in two directions at once.When you use a pipe, output flows from one command to the next and disappears. With tee, you can save the output to a file while still passing it downstream.
Normal pipe:
CommandA → CommandB (what's in the middle is gone)
With tee:
CommandA → tee ──→ saved to file
↓
flows to CommandB tooWhere the name comes from
The capital letter "T" — one input, two outputs. Same idea as a T-junction in plumbing.
Basic Usage
Conclusion: Insert
tee filenamein a pipeline to display output while saving it to a file.
tee filename in the middle of your pipeline!command | tee filename
Example: display ls -la output on screen and save it to list.txt
ls -la | tee list.txt
Both happen at the same time — the output appears on screen and gets written to list.txt.
What tee gives you
- Screen output: uninterrupted, as if tee wasn't there
- File save: happens simultaneously
tee vs > Redirect
command | tee file different from command > file?>, the output goes only to the file — nothing shows on screen. With tee, you get both.| Method | Screen output | File save |
|---|---|---|
command |
yes | no |
command > file |
no | yes |
command | tee file |
yes | yes |
Use > when you just want to store output silently. Use tee when you want to watch it happen and save it at the same time.
Saving Logs While Watching Output
Conclusion: Add
2>&1 | tee install.logto capture all output while watching it scroll.
make install 2>&1 | tee install.log
2>&1 redirects stderr (error messages) into the same stream as stdout, so both end up in the log file.
What 2>&1 means
1= stdout (normal output)2= stderr (error messages)2>&1= merge stderr into stdout
Without this, error messages go only to the terminal and never reach tee.
The -a Flag: Append Instead of Overwrite
Conclusion:
teeoverwrites by default — use-ato append and preserve previous entries.
-a if you want to append instead.command | tee -a filename
Example: accumulate run timestamps in one log file
date | tee -a run.log date | tee -a run.log cat run.log
Mon Jun 1 03:00:00 UTC 2026 Mon Jun 1 03:00:05 UTC 2026
Without -a, every tee call overwrites the file from scratch. Use -a whenever you want to preserve previous entries.
Writing to Multiple Files
Conclusion: List multiple filenames after
teeto write the same output to all at once.
command | tee file1 file2
Example: save to both /tmp/result.txt and ~/backup.txt
ls -la | tee /tmp/result.txt ~/backup.txt
All listed files receive the same content. You can list as many as you need.
The sudo tee Pattern
Conclusion:
sudo echo > filefails; useecho ... | sudo tee -a /etc/fileinstead.
sudo tee shines. It's a classic Linux pattern that trips up a lot of beginners.You might expect this to work — but it doesn't:
# This fails sudo echo "127.0.0.1 example.local" >> /etc/hosts
Why sudo echo > file fails
sudo only applies to the echo command itself. The >> redirect is processed by the shell, which runs as your regular user. The shell tries to open /etc/hosts for writing before sudo echo even runs — and gets denied.
The correct approach is sudo tee:
echo "127.0.0.1 example.local" | sudo tee -a /etc/hosts
Here, echo runs as your user (fine — it just writes to stdout), and sudo tee runs as root and does the privileged write.
tee prints the content to the terminal as well. To suppress that output, redirect stdout to /dev/null:
echo "127.0.0.1 example.local" | sudo tee -a /etc/hosts > /dev/null
Always back up before editing system files
sudo cp /etc/hosts /etc/hosts.bak
Mistakes in /etc/hosts or similar files can break your system's network resolution.
Debugging Pipelines
Conclusion: Insert
tee /tmp/stage.txtmid-pipeline to snapshot data without breaking flow.
tee at any point to snapshot the data at that stage — without breaking the flow.cat access.log | grep "ERROR" | tee /tmp/errors.txt | sort | uniq -c
What this does:
grep "ERROR"filters the logteesaves those matching lines to/tmp/errors.txtsort | uniq -ccounts occurrences
You can then inspect /tmp/errors.txt separately to see exactly what went into the sorting step — useful when the final output looks unexpected.
For deep pipeline debugging, add multiple tee calls at different stages:
cat data.txt | step1 | tee /tmp/stage1.txt | step2 | tee /tmp/stage2.txt | step3
Compare the stage files to isolate exactly where things go wrong.
Common Patterns at a Glance
Conclusion: Six
teepatterns cover it all: save, append, multi-file, sudo, debug, stderr.
sudo tee, you'll use it all the time for config file edits. It's one of those small commands that shows up everywhere in real Linux work.| Use case | Command |
|---|---|
| Display and save at the same time | command | tee file.txt |
| Append without overwriting | command | tee -a file.txt |
| Save to multiple files | command | tee file1 file2 |
| Write to a root-owned file | echo "..." | sudo tee -a /etc/hosts |
| Snapshot pipeline midpoint | cmd1 | tee /tmp/debug.txt | cmd2 |
| Capture all output including error | command 2>&1 | tee output.log |