3

This question already has an answer here:

Just wondering if there is any difference between:

  echo "running the npm patch" >&2;

and

 echo "running the npm patch" &>2;

I have actually never really understand that syntax.

marked as duplicate by muru, shirish, Kiwy, Jeff Schaller, Anthony Geoghegan May 15 '18 at 17:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

7

Read the Redirection section of the manual carefully: https://www.gnu.org/software/bash/manual/bashref.html#Redirections


The cmd >&2 form is described in section "3.6.8 Duplicating File Descriptors"

[n]>&word

Here, n is not specified so it defaults to "1" meaning stdout: we are redirecting stdout to file descriptor "2" meaning stderr. All normal output from the command will be sent to stderr.


The cmd &>2 form is described in section "3.6.4 Redirecting Standard Output and Standard Error"

There are two formats for redirecting standard output and standard error:

&>word

and

>&word

Of the two forms, the first is preferred. This is semantically equivalent to

>word 2>&1

In this case, "word" is "2", so we have both stdout and stderr from the command being sent to a file named 2.

$ sh -c 'echo stdout; echo stderr >&2' &>2
$ ls -l 2
-rw-rw-r-- 1 jackman jackman 14 May 14 21:40 2
$ cat 2
stdout
stderr

I found this all very confusing when I was learning. Keep at it. Remember that redirections happen in strict left-to-right order. For example

$ sh -c 'echo stdout; echo stderr >&2' >&2 2>some.file
stdout
$ cat some.file
stderr

Why isn't the "stdout" string sent to that file?

Going from left to right:

  • 1>&2 -- I think of this as "redirect file descriptor 1 to whatever file descriptor 2 is currently using". Currently, fd 2 points to /dev/stderr. So now, fd 1 also points to /dev/stderr.
  • 2>some.file -- We change fd 2 to write to the named file. This does not alter what fd 1 is currently using.

If we were to change the order of the redirections, we'd get a different result:

$ sh -c 'echo stdout; echo stderr >&2' 2>some.file >&2
$ cat some.file 
stdout
stderr

Because we change fd 2 first. Then redirect fd 1 to whatever fd 2 is currently using.

Note that my terminology is probably wrong ("point to", etc). This is how I remember how redirections work.

  • 1
    Please note that &>2 is a bashism, and is in violation of the shell language spec which requires that cmd &> word be treated the same as cmd & > word. (Running cmd asychronously, followed by a second command list that begins with a redirection.) – William Pursell May 15 '18 at 13:06
  • 1
    Is still have 1 question though. I keep seeing interactive scripts using something like >&2 printf "something". Why is that even useful? – Rafael Eyng Feb 8 at 12:16
  • 1
    redirections can be placed anywhere in the line. Recall that the shell processes redirections before executing the command. I also put them at the end. Put them wherever is best for you. – glenn jackman Feb 8 at 12:29

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