Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

Linux tee: See the Output and Save It at the Same Time

Sean

Platform Writer

Jul 18, 2026
6 min read

tee reads from standard input and writes it to both a file and standard output at once - so you see a command’s output on screen and capture it to a file in the same run. command | tee output.log shows you the output live and writes it to output.log. It solves a specific annoyance: redirecting with > sends everything to the file and shows you nothing, so you cannot watch a long job while also keeping its log. tee gives you both. Add -a to append instead of overwrite.

Linux tee: See the Output and Save It at the Same Time

The name is a plumbing pun - a T-shaped pipe fitting that splits one flow into two. That is exactly what the command does: the data goes to the file and to the screen, splitting where the tee sits in the pipeline.

Table of contents

The basic use

ls -l | tee listing.txt

That prints the directory listing to your screen and writes the same listing to listing.txt. Without tee, you would have to choose: ls -l shows it, ls -l > listing.txt saves it silently. tee does both.

The classic case is a long-running command you want to watch and keep:

./deploy.sh | tee deploy.log

You see the deploy scroll by in real time, and when it finishes - or fails - the whole thing is in deploy.log to read back or send to someone. This is the everyday value of tee: never having to pick between watching and logging.

Append with -a

By default tee overwrites the file. To add to it instead, use -a:

echo "run 1" | tee log.txt        # creates/overwrites log.txt
echo "run 2" | tee -a log.txt     # appends to log.txt

-a is the difference between a fresh file each time and a growing log. For anything you run repeatedly and want a history of - a cron job, a monitoring loop, a series of test runs - -a is what keeps the previous output.

The relationship mirrors shell redirection: tee is like >, tee -a is like >>. If you already think in terms of overwrite versus append for > and >>, tee and tee -a are the same idea, with the bonus of also showing the output on screen.

The reason tee exists: sudo in a pipeline

Here is the problem tee solves that nothing else does cleanly. This does not work:

echo "net.ipv4.ip_forward=1" | sudo >> /etc/sysctl.conf   # FAILS

The redirection >> is performed by your shell, not by sudo, so it runs as you - and you do not have permission to write to /etc/sysctl.conf. The sudo only applies to echo, which does not need it.

tee fixes this because tee is the program doing the writing, and you can run tee itself under sudo:

echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf

Now the privileged program is tee, which opens the file with root permissions and writes to it. This is the single most common reason people learn tee - writing to a protected file from a pipeline. Redirection cannot do it; tee can.

Capturing stderr too

tee only sees what is piped into it, which is standard output. Error messages go to standard error and bypass the pipe. To capture both, redirect stderr into stdout first:

./build.sh 2>&1 | tee build.log

2>&1 merges stderr into stdout before the pipe, so tee sees everything - normal output and errors together - and writes it all to build.log. Without the 2>&1, errors would still print to your screen but would not land in the log, which is exactly the output you most want to keep.

The order matters: 2>&1 has to come before the pipe. Put it after and it does nothing useful. For any build, test, or deploy where you care about the errors as much as the output - which is most of them - 2>&1 | tee is the pattern to remember.

Writing to several files, and to a command

tee can write to multiple files at once:

ps aux | tee procs.txt backup.txt

That writes the same output to both files and the screen. Handy when you want a copy in two places.

And because tee also writes to standard output, you can keep piping after it - inspecting the stream mid-pipeline without interrupting it:

cat access.log | tee full.log | grep " 500 " | wc -l

Here tee saves the complete log to full.log while the pipeline continues to filter for 500s and count them. The whole stream is preserved and the downstream processing still runs. This mid-pipeline tap - save everything here, keep processing - is a clean way to debug a long pipeline or archive an intermediate stage without breaking the flow.

How this fits the rest of the stack

tee is a local trick for not losing the output of a command you ran by hand - which is a symptom of doing operations on a box directly. A platform that captures build and run output as durable logs you can search removes the need to remember 2>&1 | tee before every important command, because the capture already happened. The RunxBuild hosting calculator lays out the service, database, storage, and bandwidth as separate line items, and the RunxBuild dashboard is where the team watches deploys, logs, and restarts as they happen.

Useful related references:

FAQ

What does the tee command do in Linux?

tee reads standard input and writes it to both one or more files and standard output at the same time. So command | tee file.log shows the output on your screen and saves it to file.log in one run, instead of having to choose between watching and logging.

How do I append instead of overwrite with tee?

Use the -a flag: command | tee -a file.log appends to the file rather than overwriting it. It is the tee equivalent of >> versus > in shell redirection, and it is how you keep a growing history across repeated runs.

Why use sudo tee instead of sudo with redirection?

Because shell redirection like >> is done by your shell as your own user, so sudo command >> /etc/file fails on a protected file. sudo tee -a /etc/file runs tee itself as root, and tee does the writing, so it has permission. It is the standard way to write to a protected file from a pipeline.

How do I capture errors with tee?

Redirect stderr into stdout before the pipe: ./build.sh 2>&1 | tee build.log. The 2>&1 merges error output into the stream that tee sees, so both normal output and errors land in the log. The 2>&1 must come before the pipe.

Can tee write to multiple files at once?

Yes. command | tee file1 file2 writes the same output to both files and the screen. Because tee also writes to standard output, you can continue the pipeline after it, tapping the stream to a file while downstream commands keep processing.

#linux tee#linux#tee#pipes#dev-infra