29

I don't quite understand how the computer reads this command.

cat file1 file2 1> file.txt 2>&1

If I understand, 2>&1 simply redirect Standard Error to Standard Output.

By that logic, the command reads to me as follows:

  1. concatenate files file1 and file2.

  2. send stdout from this operation to file.txt.

  3. send stderr to stdout.

  4. end?

I'm not sure what the computer's doing. By my logic, the command should be

cat file1 file2 2>&1 > file.txt

but this is not correct.

45

I find it easier to think of using assignments.

  • > is like =
  • & is like $

You start out with

1 = /dev/tty
2 = /dev/tty

then your first example, 1> file.txt 2>&1, does

1 = file.txt
2 = $1           # and currently $1 = file.txt

leaving you with

1 = file.txt
2 = file.txt

If you did it the other way, again you start with

1 = /dev/tty
2 = /dev/tty

then 2>&1 > file.txt does

2 = $1           # and currently $1 = /dev/tty
1 = file.txt

so the end result is

1 = file.txt
2 = /dev/tty

and you've only redirected stdout, not stderr.

  • i sort of get the analogy, but it's confusing - what does the $ stand for? – Eliran Malka Jun 24 at 14:28
  • In an assignment like var=$othervar, $ introduces the variable name on the right hand side. In a redirection like 2>&1, & introduces the file descriptor number on the right hand side. I'm saying you can think of it like "file 2 equals file 1". (But there are two types of equals: < means "for reading" and > means "for writing".) – Mikel Jun 25 at 15:48
11

The order of redirection is important, and they should be read left to right.

For example: command 2>&1 >somefile means:

  1. Redirect stderr (namely 2) to the current destination of stdout (at this point, the terminal).
  2. Then change stdout to go to somefile.

So in this case, stderr goes to the terminal, and stdout goes to a file, which isn't what you probably want.

On the other hand, command >somefile 2>&1 means:

  1. Redirect stdout to somefile
  2. Then redirect stderr to the same destination as stdout (somefile).

In this last case both stderr and stdout go to somefile, which is probably what you want.

4
cat file1 file2 1> file.txt 2>&1

>& Actually means duplicate, it uses the dup system call to to map a new file descriptor onto an already opened file.

So, you (bash actually) must first open the new stdout before, saying " and redirect stderr to whatever stdout is currently set."

  • this is awesome! i been wondering about that &. could you enclose some references to that syntax, or - better yet - some good resources on the aforementioned dup system? – Eliran Malka Jun 24 at 14:59
  • 1
    'man dup' documents the the system call. – X Tian Jun 24 at 15:12
  • makes sense :) thanx – Eliran Malka Jun 25 at 7:39

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.