2

This question already has an answer here:

I have come to understand that we have two methods of redirecting both stdout and stderr to the same file. The first method is: ls -l /bin > ls-output.txt 2>&1 As the author of this book states: Using this method, we perform 2 redirections, first we redirect stdout to ls-output.txt and then we redirect stderr(file descriptor 2) to stdout(using file descriptor 1).

The order of redirections is important.

ls -l /bin 2>&1 >ls-output.txt would redirect stderr to screen.

My question is: Like in many programming languages, was the command designed with some associativity and precedence rules in mind and how do we read the command while writing it on screen? and what is the sequence of the backend execution of the command?

Here's what i think about the execution sequence: First, the command ls -l /bin sends its output to stdout and error to stderr(any one of those). Then, the stderr is redirected to stdout.(if there is any error, eg: if ls -l /binn is used) Now, the stdout stream contains one of the two(either output or error) which it then redirects to the file ls-output.txt

marked as duplicate by Gilles bash Jan 5 '15 at 23:29

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.

  • 2
    The redirection happens before ls ever starts. It's handled by the shell. See, for example, the Bash Hackers Wiki, or the links in this SO question. – muru Jan 5 '15 at 12:47
  • Your question asks about standard output and standard error. Why does the title refer to standard input? – Barmar Jan 5 '15 at 21:47
  • @Barmar, sorry it was a typo, thanks for pointing it out :) – Aman Jan 12 '15 at 18:50
4

Redirections are processed from left to right. When you execute:

ls -l /bin >ls-output.txt 2>&1

the shell performs approximately the following operations internally:

fork(); // Then in the child process:
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
// 2>&1
dup2(1, 2);

Then it executes the ls -l /bin command with these descriptor attachments in place. Since you redirect stdout to the file first, the redirection of stderr inherits that redirection.

If you were to write

ls -l /bin 2>&1 >ls-output.txt

The order of operations would be inverted:

// 2>&1
dup2(1, 2);
// >ls-output.txt
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);

This connects stderr to the original stdout, which is likely to be the terminal. Then it redirects stdout to a file; this has no effect on stderr.

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