Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Linux & Mac & Bash Command Dictionary

  1. Home
  2. Linux & Mac & Bash Command Dictionary
  3. tee

tee

Since: All Linux
macOS(2001 Cheetah)
Bash 1.0(1989)

tee reads from standard input and writes to both standard output and one or more files simultaneously. The name comes from the T-shaped pipe fitting. It is useful when you want to save a build log to a file while still seeing the output in the terminal.

Syntax

command | tee [options] [file...]

Options

OptionDescription
tee fileWrites standard input to a file and also passes it to standard output.
tee -a fileAppends to a file instead of overwriting it.
tee file1 file2Writes to multiple files at the same time.
tee /dev/nullPasses data through to standard output only, effectively the same as cat.

Sample Code

The following examples demonstrate how tee works. Think of tee as a T-shaped pipe fitting that splits the data stream in two directions.

sample_tee.sh
# Data flow:
# command output → tee → saved to file
#                    └→ standard output (to next command)

Writes standard input to a file while also passing it to standard output.

echo "Hello" | tee output.txt
Hello
cat output.txt
Hello

Displays build output in the terminal while saving it to a log file. Using 2>&1 includes standard error as well.

make 2>&1 | tee build.log

The -a flag appends to the file instead of overwriting it. This example appends to a log file while filtering for only errors and warnings.

make 2>&1 | tee -a build.log | grep -E "error|warning"

Writes to multiple files at the same time.

echo "test data" | tee file1.txt file2.txt file3.txt
test data

Use sudo tee to write to a file that requires root privileges. sudo echo > /etc/hosts fails because the shell runs the redirect outside of sudo's permissions, but piping through sudo tee writes the file correctly.

echo "127.0.0.1 myapp.local" | sudo tee -a /etc/hosts
127.0.0.1 myapp.local

Saves an intermediate result to a file mid-pipeline so you can inspect it later.

cat access.log | tee /tmp/debug.log | grep "ERROR" | wc -l
3

Inside a script, log timestamped output to a file while still displaying it in the terminal.

deploy.sh
LOG_FILE="/var/log/deploy_$(date +%Y%m%d).log"

run_step() {
  echo "[$(date '+%H:%M:%S')] $1"
}

run_step "Running git pull..."    | tee -a "$LOG_FILE"
git pull origin main 2>&1        | tee -a "$LOG_FILE"
run_step "Running npm install..." | tee -a "$LOG_FILE"
npm install 2>&1                  | tee -a "$LOG_FILE"
run_step "Done"                   | tee -a "$LOG_FILE"

Combine with process substitution (>(...)) to stream all output to the terminal while writing only errors and warnings to a separate file.

make 2>&1 | tee >(grep -E "error|warning" > errors.log) > build.log

Use tee /dev/stderr to copy data to standard error mid-pipeline. Useful when you want to inspect a value at an intermediate step while letting the pipeline continue.

echo "target data" | tee /dev/stderr | wc -c
target data
12

Common Mistakes

Common Mistake 1: tee without -a overwrites the log file each time

By default, tee overwrites the file. When recording incremental logs in a script, always use -a to append.

echo "step 1 done" | tee deploy.log
echo "step 2 done" | tee deploy.log

Run the following command:

cat deploy.log
step 2 done
(step 1 is gone — tee overwrote the file)

Use tee -a to append to the file instead.

echo "step 1 done" | tee -a deploy.log
echo "step 2 done" | tee -a deploy.log
cat deploy.log
step 1 done
step 2 done

Common Mistake 2: sudo echo cannot write to a root-owned file

The shell handles the redirect before sudo runs, so the redirect itself is executed without root privileges. This causes a "permission denied" error.

sudo echo "127.0.0.1 myapp.local" > /etc/hosts
bash: /etc/hosts: Permission denied

Pipe to sudo tee instead. The elevated privilege covers the write operation.

echo "127.0.0.1 myapp.local" | sudo tee -a /etc/hosts
127.0.0.1 myapp.local

Notes

The sudo tee pattern is a common idiom for writing to files that require root privileges. sudo echo "..." > /etc/hosts fails because the shell executes the redirect without sudo's elevated permissions, but using sudo tee via a pipe writes the file correctly.

For more on pipes, see Pipe (|). For more on redirection, see Output Redirection (>).

If you find any errors or copyright issues, please .