What Does "2>&1" Mean in Linux and Bash?
The 2>&1
syntax is one of the most commonly seen but least understood pieces of Linux command line syntax. You'll encounter it frequently in scripts, log redirections, and system administration tasks, but its meaning isn't immediately obvious to newcomers.
This guide explains what 2>&1
means, how it works with Linux streams, and provides practical examples of when and how to use it effectively in your daily work.
Understanding Linux Streams
Before diving into 2>&1
, you need to understand the concept of streams in Linux. Every process has three default streams:
- Standard Input (stdin) - File descriptor 0
- Standard Output (stdout) - File descriptor 1
- Standard Error (stderr) - File descriptor 2
These streams allow programs to receive input and send output or error messages. By default, both stdout and stderr display on your terminal, but they're actually separate streams that can be handled independently.
# This command will show both output and errors on terminal
ls /existing-directory /non-existent-directory
The command above will display the directory listing (stdout) and an error message about the non-existent directory (stderr) both on your screen, but they're using different streams.
Breaking Down 2>&1
The 2>&1
syntax is a redirection operator that means "redirect file descriptor 2 (stderr) to the same place as file descriptor 1 (stdout)". Let's break this down:
2
refers to stderr (standard error)>
is the redirection operator&1
refers to stdout (standard output)
The &
before the 1
is crucial - it tells the shell that 1
refers to a file descriptor, not a file named "1".
Basic Examples
Here's how 2>&1
works in practice:
# Without 2>&1 - errors go to terminal, output goes to file
ls /existing-directory /non-existent-directory > output.txt
# With 2>&1 - both output and errors go to file
ls /existing-directory /non-existent-directory > output.txt 2>&1
In the first example, you'll see the error on your terminal but the successful output goes to the file. In the second example, both the output and error messages are saved to the file.
Common Use Cases
Logging Everything to a File
When running scripts or commands where you want to capture all output:
# Capture both successful output and errors
./my-script.sh > logfile.txt 2>&1
This is particularly useful for cron jobs where you want to log everything:
# In crontab
0 2 * * * /path/to/backup-script.sh > /var/log/backup.log 2>&1
Discarding All Output
Sometimes you want to suppress both output and errors completely:
# Redirect everything to /dev/null (discard)
noisy-command > /dev/null 2>&1
This is commonly used when you only care about the exit status of a command, not its output.
Piping Both Streams
When you want to pipe both stdout and stderr to another command:
# Send both output and errors to grep
./my-script.sh 2>&1 | grep "ERROR"
Without 2>&1
, the pipe would only receive stdout, and error messages would still appear on your terminal.
Order Matters
The order of redirections is important. These two commands are different:
# Correct: stdout goes to file, stderr goes to same place as stdout
command > file.txt 2>&1
# Different: stderr goes to file, stdout goes to same place as stderr
command 2>&1 > file.txt
In the second example, stderr is redirected to the terminal (where stdout was originally going), then stdout is redirected to the file. This results in stderr going to the terminal and stdout going to the file.
Advanced Redirection Examples
Separating Streams
You can redirect stdout and stderr to different files:
# stdout to one file, stderr to another
command > output.txt 2> errors.txt
Combining with Other Redirections
You can combine 2>&1
with other redirection operators:
# Append both stdout and stderr to a file
command >> logfile.txt 2>&1
# Send stdout to file, stderr to another command
command > output.txt 2>&1 | logger -t mycommand
Real-World Examples
Database Backup with Logging
#!/bin/bash
# Backup script that logs everything
mysqldump -u root -p database_name > backup.sql 2>&1
if [ $? -eq 0 ]; then
echo "Backup completed successfully" >> backup.log 2>&1
else
echo "Backup failed" >> backup.log 2>&1
fi
System Monitoring Script
#!/bin/bash
# Monitor system and log all output
{
echo "=== System Check $(date) ==="
df -h
free -m
ps aux --sort=-%cpu | head -10
} > system-report.txt 2>&1
Application Startup
# Start application and capture all output for debugging
java -jar myapp.jar > app.log 2>&1 &
The &
at the end runs the command in the background, while 2>&1
ensures all output goes to the log file.
Using with Process Substitution
You can combine 2>&1
with process substitution for advanced scenarios:
# Send output to logger while also saving to file
command 2>&1 | tee >(logger -t mycommand) > output.txt
This sends both stdout and stderr to tee
, which then sends the output to both the logger command and the output file.
Debugging Redirection
To understand what's happening with your redirections, you can use the exec
command to show file descriptors:
# Show where file descriptors point
exec 2>&1
ls -l /proc/self/fd/
This helps you verify that your redirections are working as expected.
Common Mistakes
Forgetting the &
# Wrong - creates a file named "1"
command 2>1
# Correct - redirects to file descriptor 1
command 2>&1
Wrong Order
# This doesn't work as expected
command 2>&1 > file.txt
# Correct order
command > file.txt 2>&1
The 2>&1
redirection is essential for proper output handling in Linux systems. Whether you're writing scripts, setting up cron jobs, or debugging applications, understanding how to combine stdout and stderr gives you precise control over where your command output goes. Practice with these examples to become comfortable with this powerful redirection technique.
Found an issue?