Redirecting Output to Both File and stdout Using tee Command

Oct 28, 2025 · Programming · 19 views · 7.8

Keywords: tee command | output redirection | standard output

Abstract: This technical article provides an in-depth exploration of redirecting command output to both files and standard output in Linux bash environments. Through detailed analysis of the tee command's working principles, syntax structure, and practical applications, combined with advanced techniques such as stderr redirection and file append modes, it offers comprehensive solutions for system administrators and developers. The article also addresses potential output buffering issues and corresponding resolution strategies, ensuring readers gain thorough understanding of this essential I/O redirection technology.

Introduction

In Linux bash environments, command output management forms the foundation of system administration and script development. The redirection of standard output (stdout) and standard error (stderr) is crucial for logging, debugging, and automation workflows. Traditionally, developers faced a choice: either display output on the terminal or redirect it to a file. However, numerous practical scenarios require achieving both objectives simultaneously, which is precisely where the tee command excels.

Fundamental Principles of tee Command

The tee command is a standard utility in Unix/Linux systems, with its name derived from the T-shaped connector in plumbing, metaphorically describing its function: splitting one input stream to multiple output destinations simultaneously. In data stream processing, tee acts as an intermediate processor that reads data from standard input and concurrently writes to standard output and one or more files.

From a technical architecture perspective, the tee command implements a typical producer-consumer pattern. Command execution output serves as the data source, tee functions as the intermediate processor, while terminal display and file storage act as different consumers. This design avoids performance overhead from data duplication while ensuring output consistency.

Basic Usage and Syntax Analysis

The most fundamental tee command usage involves piping the output from a previous command to tee:

command | tee filename

Let's examine its working mechanism through a concrete code example. Suppose we need to list files in the current directory while displaying and saving the results simultaneously:

#!/bin/bash
# Basic tee usage example
ls -la | tee directory_listing.txt

echo "Checking file contents:"
cat directory_listing.txt | head -5

In this example, the ls command output is piped to tee, which sends data concurrently to standard output (terminal display) and the specified file directory_listing.txt. This approach's advantage lies in maintaining output real-time characteristics, allowing users to see results immediately on the terminal while data is persistently saved.

Comprehensive Redirection Including Standard Error

In practical applications, redirecting only standard output often proves insufficient. Many programs output error messages to the standard error stream. To capture complete execution records, stderr must also be redirected into tee's processing pipeline.

Using the 2>&1 operator redirects standard error to standard output:

command 2>&1 | tee output.log

Let's demonstrate this usage through a more complex example:

#!/bin/bash
# Comprehensive redirection including stderr example

echo "Starting complex command execution..."
find /etc -name "*.conf" 2>&1 | tee find_results.log

echo "Execution completed, checking log file:"
wc -l find_results.log

echo "Last few lines of output:"
tail -3 find_results.log

In this example, the find command might encounter permission-denied errors, which are redirected to standard output via 2>&1, then processed by tee to output simultaneously to terminal and log file. This approach ensures all output information—whether normal listing results or error messages—is completely recorded.

File Append Mode

In certain scenarios, we need to accumulate output from multiple executions into the same log file rather than overwriting each time. The tee command's -a option supports append mode:

command 2>&1 | tee -a logfile.txt

The following example demonstrates append mode's practical application:

#!/bin/bash
# Append mode usage example

echo "=== First execution $(date) ===" | tee -a execution_log.txt
ls -l | tee -a execution_log.txt

echo "=== Second execution $(date) ===" | tee -a execution_log.txt
df -h | tee -a execution_log.txt

echo "Complete execution log:"
cat execution_log.txt

This mode proves particularly suitable for long-running monitoring scripts or operations requiring historical records, where each execution's results are chronologically arranged in the file for subsequent analysis.

Output Buffering Issues and Solutions

Although the tee command is powerful, output buffering issues may arise in practical usage. Many programs buffer output to enhance performance, potentially causing delays in terminal display and file writing.

Buffering problems manifest primarily in two aspects: first, when standard output and standard error employ different buffering strategies, mixed output may experience sequence disorders; second, for programs with low output frequency, users might not see any output for extended periods because data remains buffered in memory unflushed.

An effective solution to buffering problems involves using the unbuffer tool, part of the expect package:

#!/bin/bash
# Using unbuffer to resolve buffering issues

# Install expect package (if needed)
# sudo apt-get install expect  # Ubuntu/Debian
# sudo yum install expect      # CentOS/RHEL

echo "Using unbuffer to ensure real-time output:"
unbuffer slow_command 2>&1 | tee realtime_output.log

unbuffer runs commands through pseudo-terminals (pty), forcing programs to use line buffering mode, thereby ensuring output displays and saves promptly. This method proves especially useful for long-running tasks requiring real-time progress monitoring.

Advanced Application Scenarios

The tee command's flexibility enables effectiveness in various complex scenarios. Below are some advanced application examples:

Multiple File Output: tee supports simultaneous output to multiple files:

#!/bin/bash
# Multiple file output example

echo "System status check" | tee system_info.log debug.log
uptime | tee -a system_info.log debug.log
free -h | tee -a system_info.log debug.log

Intermediate Processing in Pipeline Chains: tee can serve as intermediate nodes in complex pipeline chains:

#!/bin/bash
# tee usage in pipeline chains

# Process data while simultaneously saving raw data and processed results
data_generator | tee raw_data.log | data_processor | tee processed_data.log | result_analyzer

Real-time Monitoring and Logging: Combined with other tools for real-time monitoring:

#!/bin/bash
# Real-time system monitoring

while true; do
    echo "=== $(date) ===" | tee -a system_monitor.log
    top -bn1 | head -10 | tee -a system_monitor.log
    sleep 60
done

Performance Considerations and Best Practices

When using the tee command, several performance optimization considerations and best practices should be addressed:

Buffer Size Adjustment: For large-volume data processing, system buffer settings can be adjusted to optimize performance. The stdbuf command controls buffering behavior:

#!/bin/bash
# Adjusting buffer sizes
stdbuf -o0 command 2>&1 | tee output.log

Error Handling: Practical scripts should incorporate appropriate error handling mechanisms:

#!/bin/bash
# tee usage with error handling

if ! command 2>&1 | tee output.log; then
    echo "Command execution failed" >&2
    exit 1
fi

Resource Management: For long-running tasks, file size management and log rotation require attention:

#!/bin/bash
# Log file management example

LOG_FILE="application.log"
MAX_SIZE=10485760  # 10MB

if [ -f "$LOG_FILE" ] && [ $(stat -f%z "$LOG_FILE") -gt $MAX_SIZE ]; then
    mv "$LOG_FILE" "${LOG_FILE}.$(date +%Y%m%d_%H%M%S)"
fi

application 2>&1 | tee -a "$LOG_FILE"

Conclusion

The tee command, as a powerful I/O redirection tool in Linux bash environments, provides elegant solutions for simultaneous output to files and standard output. By mastering its basic usage, understanding output buffering mechanisms, and applying advanced techniques, developers and system administrators can manage command output more effectively to meet various complex operational and development requirements. Whether for simple logging or sophisticated real-time monitoring systems, the tee command plays significant roles and represents an essential tool every Linux user should thoroughly master.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.