How to redirect standard (stderr) error in bash

See all Bash/Shell scripting related FAQ
I am trying to redirect bash message into file named output.log. But, it is not getting redirected. How do I redirect both standard output and standard error in bash shell? In Linux, how do I redirect error messages?

Standard error (also known as stderr) is the default error output device. Use stderr to write all system error messages. The number (FD – File Descriptors) two (2) denotes the stderr. The default stderr is the screen or monitor. Standard output (also known as stdout) is used by a command to writes (display) its output. The default stdout is the screen. It is denoted by one number (1).
Tutorial details
Difficulty level Easy
Root privileges No
Requirements Linux, macOS or Unix-like OS with Bash
Est. reading time 4 minutes

2> is input redirection symbol and syntax is:

  1. To redirect stderr (standard error) to a file:
    command 2> errors.txt
  2. Let us redirect both stderr and stdout (standard output):
    command &> output.txt
  3. Finally, we can redirect stdout to a file named myoutput.txt, and then redirect stderr to stdout using 2>&1 (errors.txt):
    command > out 2>errors.txt

Make sure you use >> for appending data/log if the file already has data. For instance:

# overwrite existing file #
command1  &> output.txt
# append existing file #
command2  &>> output.txt
# append stdout and stderr to differnet files #
my_command 2>err.log 1>out.log

How to redirect standard error in bash
You must replace command with the command you want to run. Let us see some examples that explains redirection of standard error in bash.

How to redirect standard error in bash

Run find command and save all error messages to find.error.txt file:
find / -name "*.conf" 2> find.error.txt
You can view find.error.txt with the cat command:
cat find.error.txt
Sample outputs:

find: ‘/boot/grub2’: Permission denied
find: ‘/proc/tty/driver’: Permission denied
find: ‘/proc/1/task/1/fd’: Permission denied
find: ‘/proc/1/task/1/fdinfo’: Permission denied
find: ‘/proc/963/task/963/ns’: Permission denied
find: ‘/proc/963/task/1078/fd’: Permission denied
find: ‘/proc/963/task/1078/fdinfo’: Permission denied
find: ‘/var/spool/postfix/public’: Permission denied
find: ‘/var/spool/postfix/saved’: Permission denied
find: ‘/var/spool/postfix/trace’: Permission denied
find: ‘/usr/share/polkit-1/rules.d’: Permission denied
find: ‘/usr/libexec/initscripts/legacy-actions/auditd’: Permission denied

You need to use “2>” when you want to redirect stderr to a file. You can redirect stdout to file named results.txt and stderr to file named errors.txt:
find / -name "*.conf" >results.txt 2>error.txt
Verify results with the cat command:
cat results.txt
cat error.txt

This is useful in shell scripts or any other purpose.

How to redirect standard error and standard output in bash

You can send both stdout and stderr to a file named output.txt
command &>output.xt
find / -name "*.pl" &>filelist.txt

Please note that both errors and actual output of the find command stored into a file:
cat filelist.txt
Sample outputs:

find: ‘/usr/share/polkit-1/rules.d’: Permission denied
find: ‘/usr/libexec/initscripts/legacy-actions/auditd’: Permission denied


Please note that examples are bash-specific and incompatible with POSIX shell scripting. For example, local is not supported by POSIX shell such as /bin/sh.

Command Description/Purpose
command 2>filename Redirect stderr to filename
command >output.txt 2>error.log
cat output.txt error.txt
Redirect stderr to file named error.log and stdout to file named output.txt
command &> filename Redirect stderr and stdout to filename
command 2>&- Just suppress error messages. No file created. No error message displayed on screen
command 1>&2
Sample code:

echo "$1" 1>&2
# add exit code 1 i.e. an unspecified error
exit 1
die "File not found"

Another example:

error_print() {
  local m="$1"
  local c=${2-1} 
  echo >&2 -e "${m}"
  exit "$code"
error_print "Failed to create directory" 2
[ ! -f "$CONFIG_FILE" ] && error_print "${CONFIG_FILE} not found."
Redirect error messages to standard output. Useful in shell script when you need to forcefully display error messages on screen

For more info see bash man page online or read it at the cli by using the man command:
man bash

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

6 comments… add one
  • calcium Nov 6, 2020 @ 10:18

    The numbers are actually file descriptors.

    • 0 = stdin
    • 1 = stdout
    • 2 = stderr
      • 🛡️ Vivek Gite (Author and Admin) Vivek Gite Nov 6, 2020 @ 10:24

        yes they are. thanks for comment.

    • Victor Dec 16, 2020 @ 6:46

      Hi, Vitek!
      It seems there is a mistake in your article, specifically the fifth example in your conclusive summarizing table is wrong in my opinion. I had tried to post you a reply, but it turned to be too long and the site refused to accept it. So I designed it as a text file, zipped it as a tar archive and uploaded to a filehosting. Please take some time, download it and read my message. Perhaps I’m wrong, still it seems to me, I’ve found a flaw in your article.

      • 🛡️ Vivek Gite (Author and Admin) Vivek Gite Dec 17, 2020 @ 5:48

        I can’t find your zip file. However, I updated my 5th example.

        • Victor Dec 17, 2020 @ 7:41

          Hi, Vivek!

          I have read your article “How to Redirect Standard Error in Bash” on the link dedicated to the redirection of standard input/output streams,
          however I couldn’t understand the meaning of your last instruction in the article and the example below.

          command 2>&1

          Redirect error messages to standard output. Useful in shell script when you need
          to forcefully display error messages on screen

          echo "$1" 2>&1
          die "File not found"

          The 2>&1 command really redirects stderr to stdout, but it seems in most cases this construction won’t work as it was thought out. In your example you redirect the stderr of echo, but echo always sends its output to stdout, not stderr, thus this redirection will take no effect and the “File not found” message will be sent to stdout any case. On the other hand, if the standard output has been already redirected to some file, say “msg.txt”, the 2>&1 construction will redirect stderr to the same “msg.txt” file and put all your error messages together with normal output.

          I think what you really meant was the construction 1>&2 which redirects stdout to stderr. Then the standard output of the script may be redirected to some file or a pipe, still the error messages will appear on the screen or a terminal. So your instruction possibly should be rewritten in some way like:


          command 1>&2

          Redirect error messages from standard output to standard error stream. Useful in a shell script when you need to forcefully display error messages on the screen, no matter was the script’s output redirected to a file or a pipe or not. The construction is useful with commands like echo or printf, which always print the text to the standard output, and makes them print error messages to the standard error stream.

          echo "$1" 1>&2
          die "File not found"

          Per contra, the 2>&1 operator is useful when you want your script’s or program’s error messages to get to the same stream as normal output. In that case it must be preceded by the stdout redirection, otherwise it won’t work. For example,

          command > file.txt 2>&1
            ## or ##
          command1 2>&1 | command2

          As far as I know, it’s a common practice to use in modern shells a brief simplified notation:

          command >& file.txt
            ## or equivalent ##
          command >> file.txt

          instead of the old traditional

          command > file.txt 2>&1

          but the meaning of both notations (modern simplified and the old verbose one)
          is quite the same. Please look through my post and comment it. I’m not a shell programming expert, so I may be wrong, but it seems I’ve found a small mistake in your article.

          • 🛡️ Vivek Gite (Author and Admin) Vivek Gite Dec 18, 2020 @ 19:37

            Thanks. I fixed the page. I appreciate your feedback.

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.