How to Redirect stderr to stdout in Bash

By 

Updated on

7 min read

Bash: Redirect stderr to stdout

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 simply a number that represents an open file. The input stream provides data to the program, usually from keyboard input. The program sends its regular output to stdout and error messages to stderr. By default, both stdout and stderr are displayed on the screen.

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:

Terminal
command > file.txt 2>&1

In Bash, you can use the shorter &> form:

Terminal
command &> file.txt

The 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:

Terminal
command > file.txt
Terminal
command 1> file.txt

To redirect standard error (stderr) to a file, use the 2> operator:

Terminal
command 2> error.txt

You can redirect stdout and stderr to two separate files:

Terminal
command 1> output.txt 2> error.txt

Redirecting 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:

Terminal
command > file.txt 2>&1

In 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:

Terminal
ls /tmp /missing-path > /tmp/redirect-demo.txt 2>&1

Display the file:

Terminal
cat /tmp/redirect-demo.txt

The 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:

Terminal
command &> file.txt

Both forms produce the same result. The &> syntax is shorter and preferred in Bash scripts, but 2>&1 is portable across all POSIX shells.

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:

Terminal
command 2>&1 > file.txt

Bash 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:

Terminal
command > file.txt 2>&1

Appending Instead of Overwriting

The > operator overwrites the target file each time. To append output to an existing file, use >>:

Terminal
command >> file.txt 2>&1

This appends stdout to file.txt and redirects stderr to the same location.

To append both streams using the shorthand syntax, use &>>:

Terminal
command &>> file.txt

Appending 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.

To pipe both stdout and stderr, redirect stderr to stdout before the pipe:

Terminal
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:

Terminal
command |& grep "error"

Both forms are equivalent. Use 2>&1 | for POSIX compatibility or |& for brevity in Bash scripts.

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:

Terminal
command 2> /dev/null

To suppress all output (both stdout and stderr):

Terminal
command &> /dev/null

To keep only error messages and discard regular output:

Terminal
command > /dev/null

This 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:

Terminal
command 2> error.log

To do the opposite, display errors on the screen while saving regular output to a file:

Terminal
command > output.log

To save both streams to separate files:

Terminal
command > output.log 2> error.log

If you need to both save and display output at the same time, use the tee command:

Terminal
command 2>&1 | tee output.log

This 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:

Terminal
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:

backup.shsh
#!/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:

Terminal
exec 2>> /var/log/backup.err

Quick Reference

SyntaxDescription
command > fileRedirect stdout to a file (overwrite)
command >> fileRedirect stdout to a file (append)
command 2> fileRedirect stderr to a file
command 2>> fileAppend stderr to a file
command > file 2>&1Redirect both stdout and stderr to a file
command &> fileShorthand for redirecting both streams (Bash)
command &>> fileAppend both streams to a file (Bash)
command 2>&1 | cmdPipe both streams to another command
command |& cmdShorthand for piping both streams (Bash)
command 2> /dev/nullDiscard error messages
command &> /dev/nullDiscard all output
exec >> file 2>&1Redirect all output for the rest of a script

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 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.

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, 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

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