What's the Difference of Redirect an Output Using ">", "&>", ">&" and "2&>"

What's the difference of redirect an output using , & , & and 2& ?


  • > redirects stdout to a file
  • 2>& redirects file handle "2" (almost always stderr) to some other file handle (it's generally written as 2>&1, which redirects stderr to the same place as stdout).
  • &> and >& redirect both stdout and stderr to a file. It's normally written as &>file (or >&file). It's functionally the same as >file 2>&1.
  • 2> redirects output to file handle 2 (usually stderr) to a file.

What does 2 &1 mean?

File descriptor 1 is the standard output (stdout).

File descriptor 2 is the standard error (stderr).

At first, 2>1 may look like a good way to redirect stderr to stdout. However, it will actually be interpreted as "redirect stderr to a file named 1".

& indicates that what follows and precedes is a file descriptor, and not a filename. Thus, we use 2>&1. Consider >& to be a redirect merger operator.

What's difference between 2 1 /dev/null and 2 &1 /dev/null ?

The & means file descriptor1. So 2>&1 redirects standard error to whatever standard output currently points at, while 2>1 redirects standard error into a file called 1.

Also, the redirects happen in order. So if you say 2>&1 >/dev/null, it redirects standard error to point at what standard output currently points at (which is probably a noop), then redirects stdout to /dev/null. You probably want >/dev/null 2>&1.


1In the context of a file redirect -- when it is the next token immediately after a > or <. In other contexts it means something else.

What's the difference between & foo and foo 2 &1 ?

From the bash manual:

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

The phrase "semantically equivalent" should settle the issue with your coworker.

linux redirection: difference between using 2 &1 before and after somfilename

Not sure about zsh but according to Bash manual:

   Note  that  the order of redirections is significant.  For example, the
command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,
while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard
error was duplicated as standard output before the standard output was
redirected to dirlist.

For ls > dirlist 2>&1, this is what happens (in pseudo C code):

fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist"
dup2(1, 2); // now stderr becomes a dup of stdout so it also points to "dirlist"

For ls 2>&1 > dirlist, this is what happens:

             // initially, both stdout and stderr point to the tty
dup2(1, 2); // now stderr becomes a dup of stdout so they still point to the tty

fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist",
// but stderr still points to tty

linux redirection: difference between using 2 &1 before and after somfilename

Not sure about zsh but according to Bash manual:

   Note  that  the order of redirections is significant.  For example, the
command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,
while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard
error was duplicated as standard output before the standard output was
redirected to dirlist.

For ls > dirlist 2>&1, this is what happens (in pseudo C code):

fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist"
dup2(1, 2); // now stderr becomes a dup of stdout so it also points to "dirlist"

For ls 2>&1 > dirlist, this is what happens:

             // initially, both stdout and stderr point to the tty
dup2(1, 2); // now stderr becomes a dup of stdout so they still point to the tty

fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist",
// but stderr still points to tty

Difference between '2 &1' and '& filename'


cat file1 file2

It will give an error like this

hello cat: file2: No such file or directory

The error is simply telling you file2 does not exist. You create file1 with your redirection:

echo hello > file1

Now file1 exists. When you do cat file1 file2, cat attempts to output the contents of file1 & file2 to stdout, but file2 doesn't exist (it tells you). To make file2, you can do cat file1 > file2 to redirect the output of cat file1 to file2, or you can simply cp file1 file2. Then file2 will exist.

I want to redirect the STDOUT and STDERR, so

cat file1 file2 > file3 2>&1 | cat
hello
cat: file2: No such file or directory

Again, file2 still doesn't exist. cat short for concatenate simply output the contents of the files given as input to stdout unless redirected. file1 contains hello so it is output along with the error. hello is redirected to file3, ...and..., since you have redirected stderr to stdout (e.g. 2>&1), the error message also ends up in file3

The | (pipe) command in Linux shell just takes the stdout from the command on the left and redirects it to the stdin of the command after the pipe. Since you already redirected the stdout and stderr from cat file1 file2 into file3, nothing is sent to the cat following the pipe. The output you posted appears to have come from:

cat file3

In a Linux shell, stdin, stdout and stderr are simply special files that represent file descriptors 0, 1 & 2, respectively. The actual files in the filesystem are /dev/stdin, /dev/stdout, and /dev/stderr. If you check with the ls -l command, you will see the relation between the file and file descriptors:

$ ls -l /dev/std*
lrwxrwxrwx 1 root root 4 Apr 2 17:47 /dev/stderr -> fd/2
lrwxrwxrwx 1 root root 4 Apr 2 17:47 /dev/stdin -> fd/0
lrwxrwxrwx 1 root root 4 Apr 2 17:47 /dev/stdout -> fd/1

How to redirect and append both standard output and standard error to a file with Bash


cmd >>file.txt 2>&1

Bash executes the redirects from left to right as follows:

  1. >>file.txt: Open file.txt in append mode and redirect stdout there.
  2. 2>&1: Redirect stderr to "where stdout is currently going". In this case, that is a file opened in append mode. In other words, the &1 reuses the file descriptor which stdout currently uses.


Related Topics



Leave a reply



Submit