3

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

Aman
  • 1,073
  • 2
  • 10
  • 18

1 Answers1

6

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.

Barmar
  • 9,927