CommandsLinux

Tee Command on Linux with Examples

Tee Command on Linux

The tee command is one of those hidden gems in the Linux toolbox that significantly enhances productivity for system administrators, developers, and power users alike. Unlike simple redirection operators, tee offers a unique capability to split command output in two directions simultaneously—displaying results on your screen while also saving them to one or more files. This T-shaped behavior is actually where the command gets its name, functioning similarly to a T-shaped pipe fitting in plumbing that divides flow in multiple directions.

In this comprehensive guide, we’ll explore everything from basic usage to advanced techniques, equipping you with the knowledge to leverage tee effectively in your Linux workflow.

Understanding the Tee Command

Before diving into examples and practical applications, let’s establish a solid understanding of what the tee command is and why it’s so valuable in Linux environments.

What is the Tee Command?

The tee command is a standard utility in Linux and Unix-like operating systems that reads from standard input (stdin) and writes the data to both standard output (stdout) and one or more files simultaneously. This dual-output functionality is what makes tee particularly useful—it bridges the gap between viewing command output immediately and preserving that output for later reference or analysis.

In its simplest form, tee acts like a T-junction in plumbing, where data flows in from one direction and is split into two separate streams. One stream goes to your terminal display, while the other is directed to a file or multiple files.

Why Use the Tee Command?

The true value of the tee command becomes apparent in several scenarios:

  1. Command Logging: When executing commands with important output, tee allows you to both see the results immediately and save them for documentation.
  2. Debugging: When troubleshooting scripts or applications, tee helps capture output while still monitoring it in real-time.
  3. System Administration: When modifying configuration files that require elevated privileges, tee provides a straightforward method to write to these files when combined with sudo.
  4. Data Processing: When building complex command pipelines, tee enables you to save intermediate results without breaking the flow of data processing.

Unlike standard redirection operators (> or >>), which send output only to a file, tee maintains the visibility of command output on your screen while simultaneously saving it. This immediate feedback is invaluable when working with critical system commands where seeing results in real-time is essential.

Tee Command Syntax and Options

Understanding the correct syntax and available options will help you get the most out of the tee command.

Basic Syntax

The standard syntax for the tee command follows this structure:

[command] | tee [options] [filename]

Here’s what each component represents:

  • [command]: The command whose output you want to capture
  • |: The pipe operator that sends output from the command to tee
  • tee: The tee command itself
  • [options]: Optional flags that modify tee’s behavior
  • [filename]: One or more files where you want to save the output

For example, to display your system’s disk usage while saving it to a file:

df -h | tee disk_usage.txt

This command shows disk usage information on your screen and saves the same data to a file named disk_usage.txt.

Common Options

The tee command supports several options that extend its functionality:

  1. -a, --append: Appends output to the specified file(s) instead of overwriting them. This is especially useful when you want to add new data to existing logs or records.
  2. -i, --ignore-interrupts: Ignores interrupt signals, ensuring tee completes writing operations even if the connected command is interrupted.
  3. -p, --output-error[=MODE]: Sets specific behaviors for write errors, with various modes available:
    • warn: Diagnoses errors when writing output
    • warn-nopipe: Diagnoses errors only when writing to non-pipe outputs
    • exit: Exits on error
    • exit-nopipe: Exits on error only when writing to non-pipe outputs
  4. --help: Displays the help manual with all available options.
  5. --version: Shows the command version information.

To see all available options for tee on your system, simply run:

tee --help

Basic Examples of the Tee Command

Let’s explore some fundamental ways to use the tee command in everyday Linux tasks.

Displaying and Saving Command Output

One of the most common uses of tee is to view command output while simultaneously storing it in a file:

ls -l | tee file_list.txt

This command lists all files in the current directory with detailed information, displaying the results on your terminal while also saving them to file_list.txt.

For system monitoring, you can capture performance statistics:

top -b -n 1 | tee system_performance.txt

This runs the top command once in batch mode and saves the output to a file while also showing it on screen—perfect for quick system checks that need documentation.

Writing to Multiple Files

Tee can write the same output to multiple files simultaneously, which is useful for creating duplicate logs or distributing information:

echo "Important system notice" | tee notice1.txt notice2.txt notice3.txt

This command writes the message to three different files while also displaying it on your terminal.

Another practical example is creating identical configuration backups:

cat /etc/ssh/sshd_config | tee sshd_backup_$(date +%Y%m%d).txt sshd_backup_latest.txt

This creates two copies of your SSH configuration—one with today’s date and another as the “latest” version.

Appending to Existing Files

By default, tee overwrites the destination file. To append content instead, use the -a option:

echo "New log entry at $(date)" | tee -a system_log.txt

This adds a timestamped entry to system_log.txt without erasing previous content—ideal for ongoing logs or records.

You can verify the append operation worked correctly by examining the file:

cat system_log.txt

This approach is particularly valuable when building logs incrementally or adding new information to existing documentation.

Advanced Tee Command Usage

Once you’ve mastered the basics, you can leverage tee for more sophisticated operations.

Combining Tee with Other Commands

Tee excels in complex command pipelines, allowing you to capture intermediate results:

grep -r "error" /var/log/ | tee error_findings.txt | wc -l

This command searches recursively for “error” in log files, saves all matching lines to error_findings.txt, and then counts the number of errors found.

Another useful example is filtering and preserving specific information:

cat logfile.txt | grep "ERROR" | tee error-log.txt | grep "Critical" > critical-errors.txt

Here, you extract all error messages from a log, save them to error-log.txt, and then further filter for critical errors into a separate file.

Using Tee with sudo

One of tee’s most powerful applications is modifying system files that require elevated privileges:

echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf

This appends Google’s DNS server to your system’s resolver configuration file. Unlike direct redirection with sudo (which would fail), this approach properly handles the permission elevation.

When editing configuration files, this technique prevents permission-denied errors:

echo "vm.swappiness=10" | sudo tee /etc/sysctl.d/99-swappiness.conf

This creates or overwrites a sysctl configuration file to adjust system swappiness without needing to open an editor with elevated privileges.

Practical Use Cases

The tee command shines in various real-world scenarios across system administration, development, and troubleshooting.

System Administration Tasks

For configuration management:

grep -v '^#' /etc/ssh/sshd_config | grep -v '^$' | tee ssh_active_settings.txt

This extracts only active (non-commented) settings from your SSH server configuration and saves them for review or documentation.

When applying system updates:

apt update && apt upgrade -y | tee system_update_$(date +%Y%m%d).log

This captures the entire update process output, creating a dated log file that can be referenced if issues arise later.

Debugging and Troubleshooting

When diagnosing application issues:

./troublesome_app --verbose 2>&1 | tee app_debug.log

This captures both standard output and error messages from an application into a single log file while also displaying them for immediate analysis.

For network diagnostics:

ping -c 10 example.com | tee ping_results.txt

This saves ping test results to a file while showing them in real-time, useful for documenting network conditions.

Automation and Scripting

Incorporating tee into shell scripts enhances logging capabilities:

#!/bin/bash
echo "Starting backup process at $(date)" | tee -a backup.log
rsync -avz /source/ /destination/ 2>&1 | tee -a backup.log
echo "Backup completed at $(date)" | tee -a backup.log

This script logs the start time, captures all rsync output (including errors), and logs the completion time to create a comprehensive record of the backup process.

For scheduled tasks:

crontab -l | tee crontab_backup.txt

This backs up your current cron jobs before making changes, ensuring you have a reference point if something goes wrong.

Comparing Tee with Similar Commands

Understanding how tee differs from other output-handling methods helps you choose the right tool for each task.

Tee vs. Simple Redirection (> and >>)

While redirection operators (> for overwrite, >> for append) also save command output to files, they don’t display that output on screen:

# Using redirection - output only goes to file
ls -la > file_list.txt

# Using tee - output goes to both screen and file
ls -la | tee file_list.txt

Tee provides immediate feedback along with storage, making it superior for interactive use and situations where you need visual confirmation.

Additionally, tee can write to multiple destinations simultaneously, which isn’t possible with basic redirection:

# This requires multiple commands with redirection
ls -la > file1.txt
cat file1.txt > file2.txt

# With tee, it's a single operation
ls -la | tee file1.txt file2.txt

The immediate dual-output capability makes tee invaluable when working with critical commands where seeing results in real-time is essential.

Tee vs. Sponge

The sponge command (from the moreutils package) reads all input before writing anything, which allows piping to the same file you’re reading from:

# This would fail with tee (truncates the file before reading)
cat file.txt | tee file.txt

# This works with sponge
cat file.txt | grep "important" | sponge file.txt

While tee writes data as it comes in, sponge buffers everything first. This makes sponge better for transforming files in-place but less suitable for real-time monitoring.

Advanced Techniques and Tips

These sophisticated techniques can help you maximize the utility of the tee command.

Hiding Standard Output

To save command output to a file without displaying it on screen:

command | tee output.txt > /dev/null

This redirects tee’s standard output to /dev/null (discarding it) while still writing to the specified file—useful for background processes or when you only need to preserve output for later review.

For a more complex example:

find / -name "*.log" 2>/dev/null | tee log_files.txt > /dev/null

This searches for all log files, silences error messages, saves the list to log_files.txt, and prevents display on the terminal.

Working with Binary Data

While tee primarily handles text output, it can also process binary data:

dd if=/dev/sda bs=512 count=1 | tee mbr_backup.bin | hexdump -C

This reads the Master Boot Record from a disk, saves a binary copy to mbr_backup.bin, and displays a hexadecimal representation of the data.

When working with binary files, be cautious about viewing the output directly in your terminal, as it may contain control characters that could affect terminal behavior.

Performance Considerations

For large outputs, tee’s performance can be optimized:

# Using a larger buffer size with dd
command | dd bs=1M | tee large_output.txt

This leverages dd’s buffering capabilities to improve performance when handling large data streams.

When processing gigabytes of data, consider the filesystem performance of your destination:

command | tee /tmp/ramdisk/large_output.txt

Using a RAM disk or high-performance storage for tee’s output file can prevent I/O bottlenecks during intensive operations.

Common Issues and Troubleshooting

Even with a seemingly straightforward command like tee, issues can arise. Here’s how to address them.

Permission Denied Errors

The most common issue with tee occurs when writing to protected files:

# This will fail
echo "new setting" | tee /etc/system.conf
# Permission denied

# Correct approach
echo "new setting" | sudo tee /etc/system.conf

Always remember to use sudo with tee (not before the command being piped) when writing to system files or directories that require elevated privileges.

For directories with complex permissions:

mkdir -p ~/logs
echo "Log entry" | tee ~/logs/application.log

Ensure the target directory exists and has appropriate write permissions before using tee.

Unexpected Output Behavior

When working with commands that use buffered output, you might not see results immediately:

# Buffered output may delay appearance in tee
long_running_command | tee output.log

# Force unbuffered operation
long_running_command | stdbuf -o0 tee output.log

Using stdbuf can force unbuffered operation, ensuring real-time output appears as it’s generated.

For applications with different output streams:

# Capture both stdout and stderr
command 2>&1 | tee complete_log.txt

# Separate stdout and stderr
command 2> >(tee stderr.log >&2) | tee stdout.log

The second example uses process substitution to capture standard error separately from standard output.

VPS Manage Service Offer
If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal!

r00t

r00t is an experienced Linux enthusiast and technical writer with a passion for open-source software. With years of hands-on experience in various Linux distributions, r00t has developed a deep understanding of the Linux ecosystem and its powerful tools. He holds certifications in SCE and has contributed to several open-source projects. r00t is dedicated to sharing her knowledge and expertise through well-researched and informative articles, helping others navigate the world of Linux with confidence.
Back to top button