Does 3>&1 imply 4>&3 5>&3 etc.? Does 3>&1 imply 4>&3 5>&3 etc.? bash bash

Does 3>&1 imply 4>&3 5>&3 etc.?


strace shows this sequence of system calls:

$ strace -o strace.log tee /proc/self/fd/{3..6} 3>&1...$ cat strace.log...openat(AT_FDCWD, "/proc/self/fd/3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4openat(AT_FDCWD, "/proc/self/fd/4", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5openat(AT_FDCWD, "/proc/self/fd/5", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6openat(AT_FDCWD, "/proc/self/fd/6", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 7...

The first line opens /proc/self/fd/3 and assigns it the next available fd number, 4. /proc/self/fd/3 is a special path. Opening it has an effect similar to duping fd 3: fd 4 points to the same place as fd 3, the tty.

The same thing happens for each successive openat() call. When the dust settles fds 4, 5, 6, and 7 are all duplicates of fd 3.

  • 1 → tty
  • 3 → tty
  • 4 → tty
  • 5 → tty
  • 6 → tty
  • 7 → tty

Note that the 3>&1 redirection isn't important. What's important is that we're asking tee to open /proc/self/fd/N where N is already in use. We should get the same result if we get rid of 3>&1 and have tee start at /proc/self/fd/2 instead. Let's see:

$ echo foo | tee /proc/self/fd/{2..6}foofoofoofoofoofoo

Confirmed! Same result.

We can also repeat the same fd number over and over. We get the same result when we hit fd 6. By the time it reaches the last one it has opened enough descriptors to make the jump to 6 possible.

$ echo foo | tee /proc/self/fd/{2,2,2,2,6}foofoofoofoofoofoo