22

I see stuff like command 1> out or with 2>&1 to redirect stderr, but sometimes I also see &> by itself, etc.

What is the best way to understand & and what it means exactly?

Eliah Kagan
  • 117,780
AJJ
  • 862

3 Answers3

28

The & in 2>&1 simply says that the number 1 is a file descriptor and not a file name. In this case the standard output file descriptor.

If you use 2>1, then this would redirect errors to a file called 1 but if you use 2>&1, then it would send it to the standard output stream.

This &> says send both, standard output and standard error, somewhere. For instance, ls <non-existent_file> &> out.file. Let me illustrate this with an example.

Setup:

  1. Create a file koko with the following content:

    #!bin/bash
    
    ls j1
    echo "koko2"
    
  2. Make it executable: chmod u+x koko

  3. Now note that j1 doesn't exist

  4. Now run ./koko &> output

  5. run cat output and you will see

    ls: cannot access 'j1': No such file or directory
    koko2
    

Both, standard error (ls: cannot access 'j1': No such file or directory) and standard output (koko2), were sent to the file output.

Now run it again but this time like so:

./koko > output

Do cat output and you will only see the koko2 like. But not the error output from the ls j1 command. That will be sent to the standard error which you will see in your terminal.

Important note thanks to @Byte Commander:

Note that in command >file 2>&1 the order of the redirection is important. If you write command 2>&1 >file instead (which is normally not what you want), it will first redirect the command's stdout to the file and after that redirect the command's stderr to its now unused stdout, so it will show up in the terminal and you could pipe it or redirect it again, but it will not be written to the file.

George Udosen
  • 36,677
  • 2
    What is &> mean? – AJJ Sep 24 '17 at 23:07
  • Is it fair to say that the ampersand in &1 and the ampersand in &> are unrelated? Seems like the second use is more of an 'and' use, where the first case is more of a special identifier. – TankorSmash Sep 25 '17 at 05:55
  • No it's a BASH specific notation for both standard error and output as stated by ByteCommander. That & is used to identify a file descriptor, remember BASH behaves a bit differently from it sh which it's master per say – George Udosen Sep 25 '17 at 06:02
  • There's a couple more meanings of the ampersand: start in background, e.g. sleep 235 &, logical AND: commandA && commandB. These are unrelated to IO redirection though. – Ruslan Sep 25 '17 at 09:36
  • @Ruslan OP is specifically talking about file discriptors – George Udosen Sep 25 '17 at 09:37
  • 1
    Note that in command >file 2>&1 the order of the redirections is important. If you write command 2>&1 >file instead (which is normally not what you want), it will first redirect the command's stdout to the file and after that redirect the command's stderr to its now unused stdout, so it will show up in the terminal and you could pipe it or redirect it again, but it will not be written to the file. – Byte Commander Sep 25 '17 at 10:24
  • yes @ByteCommander I am aware of that will add it to my answer – George Udosen Sep 25 '17 at 10:27
  • 2
    "That will be sent to the standard output which you will see in your terminal." shouldn't this be "to the standard error"? – frarugi87 Sep 25 '17 at 13:32
  • 1
    Yes @frarugi87 your right corrected – George Udosen Sep 25 '17 at 13:38
  • 1
    @George wow, you were fast ;) Good work – frarugi87 Sep 25 '17 at 13:39
7

> FILE 2>&1 and &> FILE are equivalent. See 8.2.3.2. Redirection of errors of in Bash Guide for Beginners Chapter 8

wjandrea
  • 14,236
  • 4
  • 48
  • 98
J. Starnes
  • 1,969
2

The [n]>&word is called Duplicating Output File Descriptor(see section 2.7.6 of POSIX Shell Language Standard). This particular behavior is feature of bourne-like shells, including ksh, dash, and bash; in fact, the standard is based around Bourne shell and ksh. Looking into tcsh and csh manuals, they apparently do not provide capability of duplicating any file descriptor, however from the description of >&, this behaves as &> in bash (that is, redirects errors and normal output to file).

In *nix like systems, including Ubuntu, you often hear that everything is file, or rather a file descriptor. The standard output is constant file descriptor 1 and standard error is file descriptor 2. So, > FILE 2>&1 technically means duplicate file descriptor 2 onto file descriptor 1. In other words of this answer :

The 2>&1 tells the shell to give the command a file descriptor 2 that is a duplicate of descriptor 1. (i.e stderr & stdout point to same fd).

The key here is to note that descriptor 1 has to be set first. Because shell processes redirections in left to right order, the command >FILE 2>&1 tells shell to rewire stdout for command to go into FILE first, and only then descriptor 2 can become copy of 1, that is 1 and 2 point to same location - FILE.

This of course goes beyond the standard error and standard output. As show in this answer, by doing 3&>2

...you duplicate (dup2 ) filedescritor 2 onto filedescriptor 3, possibly closing filedescriptor 3 if it's already open

Example of manipulating file descriptors, among many, would be capturing output of dialog command into variable

It's also worth noting that &> is specific to bash. In zsh this behaves the same, but according to documentation, "...does not have the same effect as ‘> word 2>&1’ in the presence of multios". In POSIX compliant /bin/sh, this is would be treated as regular redirection with putting command into background. See also, Is there any sh code that is not syntactically valid bash code?.

See also:

Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497