I have the following shell script:

error=$(mkdir test 2>&1)

I know that the variable 'error' will get the error result of the mkdir command if there is an error, but I can't understand how 2>&1 works, could someone explain it? Thanks!

  • 1
    TL:DR summary of the answers: it captures stderr and stdout, by redirecting stderr to wherever stdout is going. – Peter Cordes Sep 22 '16 at 0:12

The syntax


will run some_command and the output of that is returned and stored in the variable "$x".

Now, normally, programs send "normal output" to the "standard out" stream (stdout, file handle #1) and error messages to the "standard error" stream (stderr, file handle #2).

The redirection semantic 2>&1 means (roughly speaking; it's a little more complicated under the covers) "send stderr to stdout". So error messages and output messages are mixed together.

So we can combine the two:

x="$(some_command 2>&1)"

will return the output and the error messages and put them into $x.

In your case

error="$(mkdir test 2>&1)"

means that $error will contain the output (which is empty) and the error (which may contain a string if an error occurs). The result is that $error will contain any error message from the mkdir command.

We can see this in action.

$ error="$(mkdir /)"
mkdir: cannot create directory '/': File exists
$ echo "$error"

$ error="$(mkdir / 2>&1)"
$ echo "$error"
mkdir: cannot create directory '/': File exists

In the first case the error message is printed immediately because it's sent to stderr, and the variable is empty. In the second case we redirect stderr to stdout and so it is captured and stored in the $error variable.

  • Thanks, you helped me a lot! It is very didactic your explanation! – Patterson Sep 22 '16 at 15:59

It means, poetically speaking: send the error stream to the same "channel" as the normal output. 2 stands for error(s). 1 is the main-line, or the standard output. &1 indicates the way, where the standard output goes. By default, it goes to the screen, and in this substitution context: $( ), it goes to the variable, becomes its value. And > is redirection. All together 2>&1 means: redirect errors the way of standard output.

  • Thanks, you helped me a lot! I like your poetic explanation! – Patterson Sep 22 '16 at 15:58
  • 1
    You're welcome. Don't forget to choose me over Stephen's dry lecture next time ! – Tomasz Sep 22 '16 at 16:02

It captures stderr and stdout, by redirecting stderr to stdout (taking effect after the $() command substitution has connected stdout to a pipe to the parent shell).

The & in >&1 makes the difference between referencing another file descriptor instead opening a file called 1.

The 2> means to redirect stderr, as usual.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.