Redirecting Standard Output and Standard Error in Bash
When executing commands in Bash, programs communicate through standard streams: standard output (stdout) for normal results, and standard error (stderr) for error messages or diagnostics. Controlling where these streams go is a fundamental skill for scripting, logging, and automation. This tutorial explains how to redirect both standard output and standard error to a file, including appending to an existing file.
Understanding Standard Streams
Before diving into redirection, it’s crucial to understand the concept of file descriptors. Bash (and most Unix-like systems) uses file descriptors to represent open files. These are small integer numbers:
- 0: Standard input (stdin) – typically the keyboard.
- 1: Standard output (stdout) – typically the terminal.
- 2: Standard error (stderr) – typically the terminal.
Redirection operators manipulate these file descriptors to change where a command sends its output.
Redirecting Standard Output
The >
operator redirects stdout to a file, overwriting the file if it exists. For example:
command > output.txt
This sends the standard output of command
to output.txt
. If output.txt
exists, its contents are truncated (deleted).
To append to a file instead of overwriting it, use the >>
operator:
command >> output.txt
This appends the standard output of command
to the end of output.txt
. If the file doesn’t exist, it’s created.
Redirecting Standard Error
The 2>
operator redirects stderr to a file, overwriting the file if it exists.
command 2> error.txt
This sends the standard error of command
to error.txt
, overwriting any existing content.
Similarly, 2>>
appends stderr to a file:
command 2>> error.txt
Redirecting Both Standard Output and Standard Error
Often, you want to capture both stdout and stderr in the same file. The key is to redirect stderr to the same destination as stdout.
Method 1: The Classic Approach (Portable)
This method works in all POSIX-compliant shells, including older versions of Bash. It’s the most portable and reliable approach:
command > output.txt 2>&1
Let’s break this down:
> output.txt
: Redirects stdout tooutput.txt
, creating or truncating the file.2>&1
: This is the critical part. It redirects file descriptor 2 (stderr) to the same location as file descriptor 1 (stdout). The&
is essential; it tells Bash that1
is a file descriptor, not a file named1
.
Method 2: Bash 4 and Later (Shorthand)
Bash version 4 introduced a shorthand operator for redirecting both stdout and stderr:
command &>> output.txt
This is equivalent to the classic method, but more concise. Note that this syntax is not portable to older Bash versions or other shells.
Choosing the Right Method
- If portability is a concern (you need your script to run on older systems or different shells), use the classic
> output.txt 2>&1
approach. - If you are confident your script will only run on Bash 4 or later, the
&>> output.txt
shorthand can make your code more readable.
Redirecting to Separate Files
You can also redirect stdout and stderr to different files:
command > output.txt 2> error.txt
This sends the standard output to output.txt
and the standard error to error.txt
. This is useful when you need to separate normal output from error messages for detailed analysis or debugging.
Example
Let’s say you have a script called my_script.sh
:
#!/bin/bash
echo "This is a normal message."
echo "This is an error message." >&2
To redirect both stdout and stderr to a file called log.txt
, you would run:
./my_script.sh &>> log.txt
The log.txt
file would contain:
This is a normal message.
This is an error message.