NeuroAgent

How to Redirect Output to File and Stdout in Bash

Learn how to redirect command output to both a file and stdout in Bash using the tee command. Complete guide with examples and advanced techniques.

Question

How to redirect command output to both a file and stdout in Bash?

In Bash, calling foo displays any output from that command on stdout.
Calling foo > output redirects any output from that command to the specified file (in this case ‘output’).

Is there a way to redirect output to a file and simultaneously display it on stdout?

NeuroAgent

You can redirect command output to both a file and stdout in Bash using the tee command. The tee command reads from standard input and writes to both standard output and one or more files simultaneously, making it perfect for this use case. For example, foo | tee output will display the output from foo on your terminal while also saving it to the ‘output’ file.

Contents

Understanding Output Redirection

In Bash, output redirection works by redirecting file descriptors. The three main standard streams are:

  • stdout (file descriptor 1): Normal output from commands
  • stderr (file descriptor 2): Error messages and diagnostics
  • stdin (file descriptor 0): Input to commands

When you use > redirection like foo > output, you’re redirecting stdout (file descriptor 1) to the specified file. This is equivalent to 1> output, where the 1 explicitly specifies the stdout file descriptor.

The basic redirection operators include:

  • > - Overwrite file with output
  • >> - Append output to file
  • < - Read input from file

However, these operators only redirect output to one destination - either to a file or to stdout, but not both simultaneously.

Using the tee Command

The tee command is the standard solution for redirecting output to both stdout and a file. Its basic syntax is:

bash
command | tee filename

For example:

bash
ls -l | tee directory_listing.txt

This command will:

  1. Show the directory listing on your terminal (stdout)
  2. Save the same output to directory_listing.txt

The tee command reads from standard input and writes to both standard output and the specified file(s).

Key Features of tee

  • Simultaneous output: Works with multiple files using -a flag
  • Append mode: Use tee -a filename to append instead of overwrite
  • Multiple files: Can write to several files at once: command | tee file1.txt file2.txt file3.txt
  • Preserves output: Maintains the original output stream for further piping

Here are some common tee usage patterns:

bash
# Basic tee usage
echo "Hello World" | tee hello.txt

# Append to file instead of overwrite
echo "Another line" | tee -a hello.txt

# Write to multiple files
ls -l | tee listing.txt backup_listing.txt

# Chain with other commands
ls -l | grep ".txt" | tee text_files.txt | wc -l

Advanced tee Usage

Handling Both stdout and stderr

If you need to capture both standard output and error messages while still displaying them, you can combine redirection with tee:

bash
# Redirect both stdout and stderr to tee
command 2>&1 | tee output.log

# Or using the &> shorthand
command &> output.log | tee output.log

Using tee in Scripts

In shell scripts, tee is particularly useful for logging while maintaining interactive output:

bash
#!/bin/bash

echo "Starting process..."
echo "Processing data..." | tee process.log
echo "Completed successfully!" | tee -a process.log

tee with Process Substitution

You can use tee with process substitution for more complex scenarios:

bash
# tee to multiple processes simultaneously
command | tee >(grep "error") >(grep "warning") error.log

Comparison with Alternative Methods

While tee is the most straightforward solution, there are alternative approaches with different characteristics:

1. Using Brace Expansion

bash
{ foo; } 2>&1 | tee output

This captures the entire command output but requires grouping.

2. Using Subshells

bash
(foo | tee output)

This runs the command in a subshell, which can be useful for scoping.

3. Using Script Redirection

You could create a wrapper script that duplicates output:

bash
#!/bin/bash
"$@" | tee "$1"

However, these alternatives are generally more complex and less readable than using tee directly.

Practical Examples

System Monitoring

bash
# Monitor system resources while logging
top -b | tee system_monitor.log

# Monitor log files in real-time
tail -f /var/log/syslog | tee -f live_syslog.log

Development and Testing

bash
# Run tests while capturing output
npm test | tee test_results.txt

# Build process logging
make all | tee build.log

Data Processing

bash
# Process CSV data while showing progress
cat large_file.csv | process_data | tee processed_data.csv

# Network monitoring while capturing packets
tcpdump -i eth0 | tee network_capture.pcap

Long-running Processes

bash
# Backup process with progress indication
rsync -av /source/ /destination/ | tee backup.log

# Compilation output
make -j4 | tee compilation.log

The Linux Shell Commands and I/O Redirection guide provides additional context on how command | tee file.txt works as a “Display and save simultaneously” operation.

According to LinuxOpsys, understanding the file descriptor system is crucial for mastering redirection in Linux, where > is synonymous with 1> for stdout redirection.

Conclusion

  • The tee command is the standard solution for redirecting output to both stdout and files in Bash, using the syntax command | tee filename
  • tee offers flexibility with options like -a for append mode and the ability to write to multiple files simultaneously
  • Unlike simple redirection, tee preserves the output stream for further piping while also saving to files
  • For most use cases, tee provides the cleanest and most readable solution compared to alternatives like brace expansion or subshells
  • Remember that tee handles only stdout by default - use 2>&1 to capture stderr as well when needed

The next time you need to save command output while still seeing it on screen, reach for the tee command - it’s the perfect tool for this common Bash scenario.