Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'd expect

echo foo | tee /proc/self/fd/{3..6} 3>&1

to fail with errors like /proc/self/fd/4: No such file or directory etc., but to my surprise, it outputs

foo
foo
foo
foo
foo

It's like 3>&1 causes all following descriptors to be redirected to stdout, except it doesn't work if I change 3 to something else, like

$ echo foo | tee /proc/self/fd/{3..6} 4>&1
tee: /proc/self/fd/3: No such file or directory
tee: /proc/self/fd/5: No such file or directory
tee: /proc/self/fd/6: No such file or directory
foo
foo
$ echo foo | tee /proc/self/fd/{4..6} 4>&1
tee: /proc/self/fd/5: No such file or directory
tee: /proc/self/fd/6: No such file or directory
foo
foo

Is there an explanation for this behavior?

like image 1000
oguz ismail Avatar asked Nov 02 '19 11:11

oguz ismail


People also ask

What can the Series 3 watch do?

With the technology, Apple Watch Series 3 models can send and receive phone calls, text messages, and email without needing to have an iPhone nearby. Thanks to the S3 dual-core processor, Series 3 watches accelerate device performance up to 70%. Wi-Fi connectivity improves, too, thanks to Apple's custom W2 chip.

When did Apple Watch 3 come out?

Launched in September 2017, the Apple Watch Series 3 keeps the classic design of earlier models but packs in quite a few new features. Alongside improvements, including the faster S3 processor and W2 wireless chip, was a cellular variant for the first time. Today, Apple sells it only in a GPS variant.

Is there a Series 7 Apple Watch?

Breaking news: Series 7 is the most durable Apple Watch ever built. Fundamental design changes were needed to achieve the vision of the larger Always-On Retina display. These same innovations also helped make the most crack‑resistant front crystal yet. Crack ResistantOur strongest front crystal ever.

What's the most recent Apple Watch?

The Apple Watch Series 7 is Apple's latest smart watch, featuring a larger always-on Retina display, a more rounded design with a larger casing, improved durability, and faster charging, starting at a price of $399.


1 Answers

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) = 4 openat(AT_FDCWD, "/proc/self/fd/4", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5 openat(AT_FDCWD, "/proc/self/fd/5", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 openat(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} foo foo foo foo foo foo 

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} foo foo foo foo foo foo 
like image 181
John Kugelman Avatar answered Oct 26 '22 23:10

John Kugelman