Home > Software engineering >  bash: duplication of file descriptors
bash: duplication of file descriptors

Time:10-19

man bash says this on redirection:

Note that the order of redirections is significant. For example, the command

          ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist, while the command

          ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard error was duplicated from the standard output before the standard output was redirected to dirlist.

I really do not understand the part:

the standard error was duplicated from the standard output before the standard output was redirected to dirlist.

From my perspective > just means redirection, like ls > dirlist redirects output of ls into file dirlist.

So 2>&1 should redirect stderr to stdout, which then should get redirected to dirlist (> dirlist). However, apparently only stdout gets redirected to dirlist then.

What's the business with this "stream A duplicated from stream B"?

CodePudding user response:

Shell redirections literally just invoke the syscall dup2(). Quoting from https://man7.org/linux/man-pages/man2/dup.2.html --

int dup2(int oldfd, int newfd);

The dup() system call allocates a new file descriptor that refers to the same open file description as the descriptor oldfd.

This isn't actually doing anything like "redirecting streams" -- instead, it's changing the table of open files to make a file handle at one position in the table be pointed to from another location in the table.

So, let's look at your first example, ls > dirlist 2>&1

  • The file dirlist is opened with open(2).
  • dup2() is used to copy the file handle created by open() to FD 1 (the default for >), and the dynamically-created handle is closed.
  • dup2() is used to copy FD 1 to FD 2.

...net result: both FD 1 and FD 2 point to dirlist.


Now, let's look at your next example, ls 2>&1 >dirlist

  • dup2() is used to copy whatever was previously opened at FD 1 to FD 2
  • open() is used to open the file dirlist
  • dup2() is used to copy the handle on dirlist to FD 1, and the dynamically-created handle is closed.

...net result: FD 2 now points to the prior value of FD 1, and FD 1 now points to dirlist.

CodePudding user response:

Your manual is a bit different from the one available at the GNU website, but take a look at Duplicating File Descriptors:

The redirection operator [n]<&word is used to duplicate input file descriptors. If word expands to one or more digits, the file descriptor denoted by n is made to be a copy of that file descriptor...The operator [n]>&word is used similarly to duplicate output file descriptors.

So when you write 2>&1 you're saying you want file descriptor 2 to become a copy of file descriptor 1. It doesn't literally get connected to file descriptor 1, it just points at the same place. Since it's just a copy, changes to file descriptor 1 don't automatically apply back to file descriptor 2. That's why the order matters.

  • Related