| |

LFCS 28 ๐Ÿง tee โ€” Splitting Output

The pipe sends the output of one command to the input of the next, and the output is consumed. The command | grep 'pattern' sends the output to the grep, and the grep prints the matching lines. But the original output is gone: the command‘s output was piped and not saved. The tee solves the problem. It reads the standard input and writes to both the standard output and one or more files. The command | tee output.txt saves the output to the file and continues the pipeline. The tee is the T-splitter, and it is the way to capture the intermediate output while the pipeline continues. The LFCS exam tests it as part of the “Use streams, pipes, and redirects” objective.

The tee is the standard tool for the logging and the debugging. The make 2>&1 | tee build.log captures the build output while displaying it. The command | tee output.txt | grep 'error' saves the full output and filters the errors. The tee -a appends to the file instead of the truncating. The tee writes to the multiple files: the command | tee file1 file2 writes to the both. The tee is the simple, and the applications are the many.

The tee has the specific behavior. It reads from the standard input and writes to the standard output and the files. The output is the unbuffered by default, and the --line-buffered makes it the line-buffered. The -i ignores the SIGINT, and the -p diagnoses the write errors. The tee returns the exit status of the failed file write, and the pipeline continues. The tee is the complement to the pipe: the pipe connects, and the tee branches.

This chapter covers three areas. First, why the tee exists โ€” the capture problem and the split. Second, the syntax and the options โ€” the -a, the -i, the -p, the --output-error, and the --line-buffered. Third, the common patterns โ€” the logging, the debugging, the multiple files, the privileged writes, and the pipeline inspection. The chapter ends with a complete example session, a quick reference, best practices, common pitfalls, real-world examples, and diagrams showing the tee flow.

Key point: The tee reads the standard input and writes to both the standard output and the files. The command | tee output.txt saves the output and continues the pipeline. The -a appends, the -i ignores the SIGINT, and the --line-buffered makes the output the line-buffered. The tee is the T-splitter, and it is the way to capture the intermediate output while the pipeline continues.


Why tee exists

The capture problem. The pipe consumes the output. The command | grep 'pattern' sends the output to the grep, and the original output is not saved. The tee captures the output while the pipeline continues: the command | tee output.txt | grep 'pattern' saves the full output to the file and the filters the lines. The tee is the branch, and the pipe is the straight line.

The logging problem. The scripts and the builds produce the output that should be the logged. The make | tee build.log captures the build output and the displays it. The tee -a build.log appends to the log across the multiple runs. The tee is the logging, and the pipe is the display.

The debugging problem. The pipeline hides the intermediate output. The command1 | command2 | command3 shows the final output, and the intermediate is the invisible. The tee inserts the inspection point: the command1 | tee step1.txt | command2 | tee step2.txt | command3 saves the each stage. The tee is the debugging tool.

The privileged-write problem. The sudo command > /root/file.txt fails, because the redirection runs in the user’s shell, not the sudo. The command | sudo tee /root/file.txt works, because the tee runs with the sudo and the writes to the file. The tee is the privileged write.

The multiple-destination problem. The output should go to the multiple places: the display, the file, and the another command. The command | tee file1 file2 | grep 'pattern' writes to the both files and the filters. The tee is the fan-out.

The trade-off. The tee adds the process to the pipeline, and the process has the overhead. The tee writes the output twice, and the disk I/O is the doubled. The tee with the large output and the slow disk is the bottleneck. The trade-off is between the capture and the performance.


a. The basic tee syntax

The tee reads the standard input and writes to the standard output and the files.

command | tee output.txt
command | tee output.txt | grep 'pattern'
command | tee -a output.txt
command | tee file1.txt file2.txt

The command | tee output.txt saves the output and the displays it. The tee is the T-splitter, and the standard output is the vertical bar.

The -a. The -a appends to the file instead of the truncating:

command | tee output.txt
command | tee -a output.txt

The first run truncates, and the second appends. The -a is the log rotation.

The -i. The -i ignores the SIGINT:

command | tee -i output.txt

The -i is the Ctrl+C handling, and it is the important for the long-running.

The -p. The -p diagnoses the write errors:

command | tee -p output.txt

The -p reports the write error on the pipe, and the GNU extension.

The --output-error. The --output-error controls the write-error behavior:

command | tee --output-error=warn output.txt
command | tee --output-error=warn-nopipe output.txt
command | tee --output-error=exit output.txt

The warn is the default, the warn-nopipe ignores the EPIPE, and the exit exits on the error.

The --line-buffered. The --line-buffered makes the output the line-buffered:

command | tee --line-buffered output.txt

The --line-buffered is the important for the live monitoring, and the default is the block-buffered.


b. The common patterns

The logging. The build and the script logging:

make 2>&1 | tee build.log
./deploy.sh 2>&1 | tee deploy.log
command | tee -a /var/log/app.log

The 2>&1 merges the stderr into the stdout, and the tee captures the both.

The pipeline inspection. The debugging of the multi-stage pipeline:

cat data.txt | tee step1.txt | sort | tee step2.txt | uniq -c | tee step3.txt

The each stage is the saved, and the inspection is the easy.

The multiple destinations. The output to the display and the files:

command | tee /tmp/output.txt /var/log/app.log

The tee writes to the both files and the standard output.

The privileged write. The sudo with the tee:

echo 'config' | sudo tee /etc/app/config.conf
echo 'config' | sudo tee -a /etc/app/config.conf

The sudo tee writes to the root-owned file, and the > does not.

The grep with the tee. The capture and the filter:

command | tee full.log | grep 'ERROR'
command | tee full.log | grep -c 'ERROR'

The full.log has the everything, and the grep shows the errors.

The tail with the tee. The live monitoring:

tail -f app.log | tee -a archive.log | grep --line-buffered 'ERROR'

The tail -f follows, the tee archives, and the grep filters with the line-buffered.

The gzip with the tee. The compress and the inspect:

command | tee >(gzip > output.gz) | grep 'pattern'

The >() is the process substitution, and the tee writes to the both.

The tee with the xargs. The intermediate with the arguments:

find . -name '*.log' | tee filelist.txt | xargs -r rm

The filelist.txt has the names, and the xargs removes them.

The password with the tee. The chpasswd:

echo 'user:password' | sudo tee /tmp/pass.txt
sudo chpasswd < /tmp/pass.txt
rm /tmp/pass.txt

The tee writes the password file, and the cleanup is the important.

The tee with the dd. The disk image:

dd if=/dev/sda | tee /dev/stderr | gzip > sda.img.gz

The tee shows the progress on the stderr and the pipes the data to the gzip.


c. The advanced patterns

The process substitution. The tee with the >():

command | tee >(gzip > out.gz) >(wc -l > count.txt) > /dev/null

The tee writes to the multiple process substitutions, and the /dev/null is the standard output discard.

The named pipe. The tee with the mkfifo:

mkfifo pipe1 pipe2
command | tee pipe1 pipe2 &
consumer1 < pipe1 &
consumer2 < pipe2 &

The tee writes to the named pipes, and the consumers read them.

The tee with the sudo. The privileged write:

command | sudo tee /etc/config.conf > /dev/null

The > /dev/null discards the standard output, and the sudo tee writes the file.

The tee with the ssh. The remote logging:

command | tee >(ssh remote 'cat > /var/log/app.log')

The tee writes to the local and the remote.

The tee with the mail. The notification:

command | tee >(mail -s 'The result' user@example.com)

The tee displays and the emails.

The tee with the logger. The syslog:

command | tee >(logger -t myapp)

The tee displays and the logs to the syslog.

The tee with the systemd-cat. The journal:

command | tee >(systemd-cat -t myapp)

The tee displays and the logs to the journal.

The tee with the parallel. The parallel processing:

command | tee >(parallel -j 4 process)

The tee displays and the parallel processes.

The tee with the split. The file splitting:

command | tee >(split -b 1M - prefix_)

The tee displays and the split writes the chunks.


Complete Example Session

# ============================================
# PART 1: THE BASIC TEE
# ============================================

command | tee output.txt
command | tee output.txt | grep 'pattern'


# ============================================
# PART 2: THE APPEND
# ============================================

command | tee output.txt
command | tee -a output.txt


# ============================================
# PART 3: THE MULTIPLE FILES
# ============================================

command | tee file1.txt file2.txt


# ============================================
# PART 4: THE PRIVILEGED WRITE
# ============================================

echo 'config' | sudo tee /etc/app/config.conf
echo 'config' | sudo tee -a /etc/app/config.conf


# ============================================
# PART 5: THE LOGGING
# ============================================

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


# ============================================
# PART 6: THE PIPELINE INSPECTION
# ============================================

cat data.txt | tee step1.txt | sort | tee step2.txt | uniq -c | tee step3.txt


# ============================================
# PART 7: THE GREP WITH THE TEE
# ============================================

command | tee full.log | grep 'ERROR'
command | tee full.log | grep -c 'ERROR'


# ============================================
# PART 8: THE LINE BUFFERED
# ============================================

tail -f app.log | tee --line-buffered archive.log | grep --line-buffered 'ERROR'


# ============================================
# PART 9: THE PROCESS SUBSTITUTION
# ============================================

command | tee >(gzip > output.gz) | grep 'pattern'
command | tee >(logger -t myapp) > /dev/null


# ============================================
# PART 10: THE LFCS PIPELINE
# ============================================

# Capture the build output while displaying it
make 2>&1 | tee build.log

# Save and filter
command 2>&1 | tee full.log | grep 'ERROR'

# The privileged write
echo 'Setting=value' | sudo tee /etc/app/settings.conf

# The append to the log
command | tee -a /var/log/app.log

# The multi-destination
command | tee /tmp/output.txt /var/log/app.log

# The pipeline inspection
cat data.txt | tee /tmp/step1.txt | sort | tee /tmp/step2.txt | uniq -c

# The live monitoring
tail -f app.log | tee -a archive.log | grep --line-buffered 'ERROR'

# The compress and inspect
command | tee >(gzip > output.gz) | wc -l

# The logger
command | tee >(logger -t myapp) | grep 'pattern'

# The parallel
command | tee >(parallel -j 4 process) | wc -l

The ten parts show the basic tee, the append, the multiple files, the privileged write, the logging, the pipeline inspection, the grep with the tee, the line-buffered, the process substitution, and the LFCS pipeline.


Quick Reference

The tee Options

The optionThe purpose
-aThe append
-iThe ignore the SIGINT
-pThe diagnose the write errors
--output-error=MODEThe write-error behavior
--line-bufferedThe line-buffered
--helpThe help
--versionThe version

The --output-error Modes

The modeThe behavior
warnThe default; the warn on the write error
warn-nopipeThe warn except the EPIPE
exitThe exit on the write error
exit-nopipeThe exit except the EPIPE

The Common Patterns

The patternThe command
The basic capturecommand | tee output.txt
The appendcommand | tee -a output.txt
The multiple filescommand | tee f1 f2
The privilegedcommand | sudo tee /etc/file
The loggingmake 2>&1 | tee build.log
The filtercommand | tee full.log | grep 'ERROR'
The livetail -f log | tee --line-buffered out
The process subcommand | tee >(gzip > out.gz)

The tee vs the >

The aspectThe teeThe >
The displayYesNo
The pipelineContinuesEnds
The multipleYesNo
The append-a>>
The sudoYesNo

The Exit Status

The statusThe meaning
0The success
1The write error
2The usage error

Best Practices

โœ… Do This:

# Use the tee for the capture and the display
make 2>&1 | tee build.log                                              # โœ…
# Use the -a for the append
command | tee -a /var/log/app.log                                      # โœ…
# Use the sudo tee for the privileged write
echo 'config' | sudo tee /etc/app/config.conf                          # โœ…
# Use the --line-buffered for the live
tail -f log | tee --line-buffered out | grep 'ERROR'                   # โœ…
# Use the tee for the pipeline inspection
cat data | tee step1.txt | sort | tee step2.txt                        # โœ…
# Use the process substitution
command | tee >(gzip > out.gz) | wc -l                                 # โœ…

โŒ Don’t Do This:

# Don't use the tee for the plain redirect
command | tee file.txt > /dev/null  # the > file.txt is the simpler      // โŒ
# Don't forget the -a for the log
command | tee /var/log/app.log  # the truncates the log                 // โŒ
# Don't use the > for the sudo
sudo command > /etc/file  # the permission denied                       // โŒ
# Don't use the block-buffered for the live
tail -f log | tee out | grep 'ERROR'  # the delayed output              // โœ… (the --line-buffered is the fix)
# Don't write to the same file
command | tee file.txt > file.txt  # the race                           // โŒ
# Don't use the tee when the redirect works
command | tee file.txt  # the > file.txt is the simpler                 // โŒ

Common Pitfalls

The pitfallThe whyThe fix
The delayed outputThe block-bufferedUse the --line-buffered
The log truncatedThe no -aAdd the -a
The sudo failsThe > redirectUse the sudo tee
The output doubledThe tee and the >Remove the one
The write errorThe full diskCheck the --output-error
The SIGINT kills the teeThe defaultUse the -i
The process substitution failsThe bash onlyUse the bash

Real-World Examples

1. The Build Log

make 2>&1 | tee build.log

2. The Deploy Log

./deploy.sh 2>&1 | tee -a deploy.log

3. The Privileged Write

echo 'key=value' | sudo tee /etc/app/config.conf

4. The Filter

command | tee full.log | grep 'ERROR'

5. The Live Monitoring

tail -f app.log | tee --line-buffered archive.log | grep 'ERROR'

6. The Pipeline Inspection

cat data | tee step1.txt | sort | tee step2.txt | uniq -c

7. The Process Substitution

command | tee >(gzip > out.gz) | wc -l

8. The Logger

command | tee >(logger -t myapp) | head

9. The Multiple Files

command | tee /tmp/out.txt /var/log/app.log

10. The Complete

make 2>&1 | tee -a build.log | grep 'ERROR'

Visual

The tee Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE tee FLOW                                                โ”‚
โ”‚                                                              โ”‚
โ”‚  command | tee output.txt | grep 'pattern'                   โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚command   โ”‚    โ”‚tee       โ”‚    โ”‚grep      โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚          โ”‚    โ”‚          โ”‚                โ”‚
โ”‚  โ”‚ the      โ”‚    โ”‚ the      โ”‚    โ”‚ the      โ”‚                โ”‚
โ”‚  โ”‚ stdout โ”€โ”€โ”ผโ”€โ”€โ”€โ–บโ”‚ stdin    โ”‚    โ”‚ stdin    โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚          โ”‚    โ”‚          โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚ output โ”€โ”€โ”ผโ”€โ”€โ”€โ–บโ”‚ stdout   โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚ .txt     โ”‚    โ”‚          โ”‚                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                              โ”‚
โ”‚  The tee splits the stream: the file and the stdout.         โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The tee vs the Redirection

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE tee vs THE REDIRECTION                                  โ”‚
โ”‚                                                              โ”‚
โ”‚  THE `>` REDIRECTION:                                        โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  command > output.txt                                โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the file has the output                          โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the terminal has the nothing                    โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the pipeline ends                               โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ”‚  THE `tee`:                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  command | tee output.txt                            โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the file has the output                          โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the terminal has the output                     โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the pipeline continues                          โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Privileged Write

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE PRIVILEGED WRITE                                        โ”‚
โ”‚                                                              โ”‚
โ”‚  โŒ THE `>` REDIRECTION:                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  sudo echo 'config' > /etc/app.conf                  โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the shell opens the /etc/app.conf as the USER   โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the permission denied                           โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ”‚  โœ… THE `tee`:                                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  echo 'config' | sudo tee /etc/app.conf              โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the tee runs as the ROOT                        โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the tee opens the /etc/app.conf as the root     โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the success                                     โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Multiple Destinations

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE MULTIPLE DESTINATIONS                                   โ”‚
โ”‚                                                              โ”‚
โ”‚  command | tee file1 file2 | grep 'pattern'                  โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚command   โ”‚    โ”‚tee       โ”‚    โ”‚grep      โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚          โ”‚    โ”‚          โ”‚                โ”‚
โ”‚  โ”‚ the      โ”‚    โ”‚ the      โ”‚    โ”‚ the      โ”‚                โ”‚
โ”‚  โ”‚ stdout โ”€โ”€โ”ผโ”€โ”€โ”€โ–บโ”‚ stdin    โ”‚    โ”‚ stdin    โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚          โ”‚    โ”‚          โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚ file1 โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ–บโ”‚ stdout   โ”‚                โ”‚
โ”‚  โ”‚          โ”‚    โ”‚ file2    โ”‚    โ”‚          โ”‚                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                              โ”‚
โ”‚  The tee writes to the multiple files and the stdout.        โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
teeThe stdin to the stdout and the files
-aThe append
-iThe ignore the SIGINT
-pThe diagnose the write errors
--line-bufferedThe line-buffered
--output-errorThe write-error behavior
The pipelineThe continues
The sudoThe privileged write
The process substitutionThe >()

Key takeaways:

  • The tee reads the standard input and writes to both the standard output and the files. The command | tee output.txt saves the output and continues the pipeline. The tee is the T-splitter, and the pipe is the straight line.
  • The -a appends to the file instead of the truncating. The command | tee -a output.txt is the log rotation, and the command | tee output.txt is the fresh capture.
  • The sudo tee writes to the root-owned file. The sudo command > /etc/file fails, because the redirection runs in the user’s shell. The command | sudo tee /etc/file works, because the tee runs with the sudo.
  • The --line-buffered makes the output the line-buffered. The default is the block-buffered, and the live monitoring needs the line-buffered. The tail -f log | tee --line-buffered out is the pattern.
  • The tee is the pipeline inspection. The command1 | tee step1.txt | command2 | tee step2.txt | command3 saves the each stage, and the debugging is the easy.
  • The tee is the logging. The make 2>&1 | tee build.log captures the both the stdout and the stderr. The 2>&1 is the merge, and the tee is the capture.
  • The tee writes to the multiple files. The command | tee file1 file2 writes to the both, and the process substitution extends the destinations.
  • The result is the output splitting. The pipe connects, and the tee branches. The result is the capture without the losing, which is the foundation of the logging and the debugging.

Remember: The tee reads the standard input and writes to the standard output and the files. The -a appends, the sudo tee writes the privileged, and the --line-buffered makes the live. The result is the output splitting, which is the foundation of the shell pipelines.



Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!