How to Redirect stderr to stdout in Bash

In Bash and other Linux shells, every running program uses three standard I/O streams. Each stream is represented by a numeric file descriptor:
0-stdin, the standard input stream.1-stdout, the standard output stream.2-stderr, the standard error stream.
A file descriptor is a number that identifies an open input or output resource. In an interactive session, stdin usually comes from the terminal. The program sends its regular output to stdout and error messages to stderr. By default, both stdout and stderr are displayed on the terminal.
For a conceptual introduction to all three channels and how commands inherit them, see the guide to stdin, stdout, and stderr in Linux .
When you redirect the output of a command to a file or pipe it to another command, you might notice that error messages still appear on the screen. This is because redirection typically affects only stdout, while stderr continues to go to the terminal.
This guide explains how to redirect stderr to stdout, redirect both streams to a file, and other common redirection patterns in Bash.
Quick Answer
To redirect stderr to the same file as stdout, place 2>&1 after the file redirection:
command > file.txt 2>&1In Bash, you can use the shorter &> form:
command &> file.txtThe order matters. command > file.txt 2>&1 sends both streams to file.txt, while command 2>&1 > file.txt sends only stdout to the file and leaves stderr on the terminal.
Redirecting Output to a File
Streams can be redirected using the n> operator, where n is the file descriptor number. When n is omitted, it defaults to 1 (standard output).
The following two commands are equivalent. Both redirect stdout to a file:
command > file.txtcommand 1> file.txtTo redirect standard error (stderr) to a file, use the 2> operator:
command 2> error.txtYou can redirect stdout and stderr to two separate files:
command 1> output.txt 2> error.txtRedirecting stderr to stdout
When saving a program’s output to a file, it is common to redirect stderr to stdout so that everything ends up in a single file.
To redirect stderr to stdout, use 2>&1:
command > file.txt 2>&1In this example, > file.txt redirects stdout to file.txt, and 2>&1 redirects stderr to the current location of stdout (which is now file.txt).
Here is a safe example you can run from any directory. The first path should exist, while the second path is intentionally missing:
ls /tmp /missing-path > /tmp/redirect-demo.txt 2>&1Display the file:
cat /tmp/redirect-demo.txtThe file contains the normal ls output for /tmp and the error message for /missing-path, because both stdout and stderr were redirected to the same destination.
Bash also provides the &> shorthand, which redirects both stdout and stderr to a file in a single operator:
command &> file.txtBoth forms produce the same result. The &> syntax is shorter and preferred in Bash scripts, but 2>&1 is portable across all POSIX shells.
Redirecting stdout to stderr
The reverse direction is just as useful. A script often needs to print a diagnostic that should not mix with the data it produces, and the >&2 operator sends that line to standard error instead of standard output:
echo "config file missing" >&2The message still shows up on your terminal, because stderr goes there by default. The difference appears once the script output is redirected or piped: the diagnostic stays out of the data stream.
>&2 is shorthand for 1>&2, and the two forms are identical. The descriptor in front of > defaults to 1, exactly as it does with > file:
echo "config file missing" 1>&2You can watch the split by sending each stream to its own file:
bash -c 'echo out; echo err >&2' > output.txt 2> error.txtoutput.txt holds out and error.txt holds err. Both echo commands ran in the same shell, but >&2 moved the second message onto a different stream.
Every well-behaved script follows this convention: results on stdout, warnings and errors on stderr. That is what lets a caller pipe your script into another command without error text corrupting the data, and it is the pattern used when a script checks whether a command exists before doing real work.
Redirection Order Matters
The order of redirection operators changes the result. In the following example, only stdout is redirected to the file, even though it looks like both streams are captured:
command 2>&1 > file.txtBash evaluates redirections left to right. 2>&1 first points stderr to wherever stdout is at that moment (the terminal), then > file.txt redirects stdout to the file. stderr keeps its earlier destination, the terminal.
Always place 2>&1 after the file redirection:
command > file.txt 2>&1A related mistake is naming the same file twice instead of using 2>&1:
command > file.txt 2> file.txtThis does not merge the streams. Each redirection opens file.txt on its own, so the command ends up holding two descriptors that track separate write positions and both start at byte zero. Whichever stream writes second overwrites part of what the first one already wrote, leaving a file with truncated, interleaved text. Use 2>&1 instead, so both descriptors share one open file and one shared position:
command > file.txt 2>&1Appending Instead of Overwriting
The > operator overwrites the target file each time. To append output to an existing file, use >>:
command >> file.txt 2>&1This appends stdout to file.txt and redirects stderr to the same location.
To append both streams using the shorthand syntax, use &>>:
command &>> file.txtAppending is useful for log files where you want to accumulate output across multiple runs.
Piping stderr Through Another Command
By default, the pipe operator (|) only passes stdout to the next command. Any error messages from the first command are printed to the terminal, not sent through the pipe.
For pipeline syntax, exit statuses, and pipefail, see our guide to Linux pipes and the | operator
.
To pipe both stdout and stderr, redirect stderr to stdout before the pipe:
command 2>&1 | grep "error"In this example, both regular output and error messages are passed to grep , which filters for lines containing “error”.
Bash also provides the |& shorthand:
command |& grep "error"Both forms are equivalent. Use 2>&1 | for POSIX compatibility or |& for brevity in Bash scripts.
Piping Only stderr
Sometimes you want the opposite: send the error messages through the pipe and throw the regular output away. Swapping the two operators does that:
command 2>&1 >/dev/null | grep "denied"Read it left to right, the way Bash does. When the shell builds a pipeline it connects stdout to the pipe first, so 2>&1 points stderr at the pipe as well. The following >/dev/null then moves stdout to /dev/null, and because stderr was already duplicated it keeps pointing at the pipe.
Here is a runnable example. The first path exists and produces normal output, while the second does not and produces an error:
ls /etc /missing-path 2>&1 >/dev/nullls: cannot access '/missing-path': No such file or directoryOnly the error line comes back. The directory listing for /etc went to /dev/null. This is a practical way to filter or count failures, such as piping the errors into wc
to see how many paths a command could not read.
Discarding Output with /dev/null
/dev/null
is a special file that discards all data written to it. Redirecting to /dev/null silences output.
To suppress error messages while keeping regular output:
command 2> /dev/nullTo suppress all output (both stdout and stderr):
command &> /dev/nullTo keep only error messages and discard regular output:
command > /dev/nullThis pattern is common in scripts where you only want to check the exit status of a command without displaying its output.
Redirecting stderr and stdout to Different Destinations
In some cases, you may want to save errors to a log file while still displaying regular output on the screen.
To redirect only stderr to a file while stdout prints normally:
command 2> error.logTo do the opposite, display errors on the screen while saving regular output to a file:
command > output.logTo save both streams to separate files:
command > output.log 2> error.logIf you need to both save and display output at the same time, use the tee command:
command 2>&1 | tee output.logThis sends the combined output to output.log and also displays it on the terminal.
To save stdout and stderr to separate files while also showing both on the terminal, use process substitution:
command > >(tee output.log) 2> >(tee error.log >&2)Each stream goes through its own tee
process. The >&2 inside the second redirect keeps error output flowing back to stderr on the terminal, so warnings stay visible.
Redirecting All Output in a Script with exec
To redirect every command’s output for the rest of a script, use the exec builtin at the top of the file. This avoids repeating >> log 2>&1 after every line:
#!/bin/bash
exec >> /var/log/backup.log 2>&1
echo "Starting backup..."
rsync -a /data/ /backup/
echo "Done."After the exec line, every later command’s stdout and stderr go to the log file. This pattern is common in cron jobs and long-running scripts where you want a single combined log without touching each command.
To redirect only stderr for the rest of the script, omit the first redirection:
exec 2>> /var/log/backup.errRedirecting stdout this way is one-way unless you save the original destination first. Copy it onto a spare descriptor, such as 3, before you redirect:
#!/bin/bash
exec 3>&1
exec >> /var/log/backup.log 2>&1
echo "Starting backup..."
echo "Backup started, see /var/log/backup.log" >&3
rsync -a /data/ /backup/
exec 1>&3 3>&-
echo "Backup finished"exec 3>&1 duplicates stdout onto descriptor 3 while it still points at the terminal. Everything after the second exec goes to the log, except the messages written explicitly to >&3, which reach the terminal instead. The closing exec 1>&3 3>&- restores stdout from the saved copy and closes descriptor 3, so the last echo prints on screen again.
Descriptors 3 through 9 are free for this kind of bookkeeping. Only 0, 1, and 2 carry fixed meanings.
Quick Reference
For a printable quick reference, see the Bash cheatsheet .
| Syntax | Description |
|---|---|
command > file | Redirect stdout to a file (overwrite) |
command >> file | Redirect stdout to a file (append) |
command 2> file | Redirect stderr to a file |
command 2>> file | Append stderr to a file |
command >&2 | Send stdout to stderr |
command > file 2>&1 | Redirect both stdout and stderr to a file |
command &> file | Shorthand for redirecting both streams (Bash) |
command &>> file | Append both streams to a file (Bash) |
command 2>&1 | cmd | Pipe both streams to another command |
command 2>&1 >/dev/null | cmd | Pipe only stderr to another command |
command |& cmd | Shorthand for piping both streams (Bash) |
command 2> /dev/null | Discard error messages |
command &> /dev/null | Discard all output |
exec >> file 2>&1 | Redirect all output for the rest of a script |
exec 3>&1 | Save the current stdout on descriptor 3 |
FAQ
What is the difference between > and >>?
The > operator overwrites the target file, while >> appends to it. Use >> when you want to add output to an existing file without erasing its contents.
What does 2>&1 mean?
It redirects file descriptor 2 (stderr) to the same destination as file descriptor 1 (stdout). The & before 1 tells Bash that 1 is a file descriptor, not a filename.
What is /dev/null?/dev/null is a special device file that discards all data written to it. Redirecting output to /dev/null effectively silences the command.
Is &> the same as 2>&1?
In Bash, command &> file is equivalent to command > file 2>&1. Both redirect stdout and stderr to the same file. However, &> is a Bash extension and is not available in all POSIX shells.
How do I print to stderr in a Bash script?
Append >&2 to the command, as in echo "error message" >&2. The full form is 1>&2, and both are the same. Use it for warnings and errors so callers can pipe your script output without diagnostics mixed into the data.
How do I redirect stderr to stdout in a pipe?
Use command 2>&1 | next_command or the Bash shorthand command |& next_command. Both send stderr and stdout through the pipe.
Can I pipe only stderr and discard stdout?
Yes. Swap the operators: command 2>&1 >/dev/null | grep pattern. The 2>&1 runs first and points stderr at the pipe, then >/dev/null discards stdout.
Conclusion
Redirecting stderr and stdout helps you capture logs, filter errors, and keep scripts quiet when needed. Use 2>&1 for portable shell syntax, &> or |& for Bash shorthand, >&2 when a script needs to report a problem, and /dev/null when you intentionally want to discard output.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page