6

This question already has an answer here:

If I type

cat > file.txt 2>&1

then file.txt is created with the content of cat's standard input.  But if I do

cat > file.txt 1>&2

then file.txt is created, but the file is empty.

What is the issue between above two commands?

marked as duplicate by John WH Smith, Michael Homer, Anthon, Stéphane Chazelas shell Feb 11 '15 at 21:34

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.

13

Order is important. The shell processes file redirections in the order that it sees them. Consider:

cat >file.txt 2>&1

First, stdout is redirected to the file file.txt. Next, stderr is redirected to stdout which is file.txt. Thus both stdout and stderr are sent to file.txt.

By contrast, consider:

cat >file.txt 1>&2

First, stdout is redirected to the file file.txt. (In doing this, file.txt is created as an empty file.) Next, stdout is redirected to stderr. Thus, stdout goes to stderr and nothing goes to file.txt and, therefore, file.txt remains as an empty file.

Another Interesting Case

Consider:

cat 2>&1 >file.txt

First, stderr is redirected to stdout which is still the terminal. Next, stdout is redirected to file.txt. This second redirection does not affect stderr. It is still sent to the terminal. It is not sent to file.txt.

Documentation

This behavior is documented in man bash:

Redirections are processed in the order they appear, from left to right.

An exception to this order, which is also documented in man bash, is pipelines. Consider:

command1 ... | command2

The standard output of command1 is sent by the pipe to the standard input of command2 and this connection is performed before any redirections specified by the first command.

An Example With Pipelines

Consider:

command1 >file.txt | command2

Because the redirection to file.txt occurs after the redirection to the pipeline, the stdout of command1 will go to file.txt. command2 will receive no input.

2

Doing '> file' is really doing '1> file'. So what you are doing is redirecting file descriptor 1 twice. Only the last one takes effect.

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