3>&1隐含4>&3 5>&3等吗?


31

我希望

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

/ proc / self / fd / 4之类的错误而失败:没有此类文件或目录等,但令我惊讶的是,它输出

foo
foo
foo
foo
foo

就像3>&1导致以下所有描述符都重定向到stdout一样,除非如果我更改3为其他内容则不起作用,例如

$ 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

有这种行为的解释吗?

Answers:


31

strace 显示以下系统调用顺序:

$ 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
...

第一行打开,/proc/self/fd/3并为其分配下一个可用的fd号码,这/proc/self/fd/3是特殊的路径4。打开它具有类似于在fd 3中进行叠加的效果:fd 4指向与tty 3 fd相同的位置。

每次后续openat()调用都会发生相同的情况。当尘埃落定时,fds 4、5、6和7都是fd 3的副本。

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

请注意,3>&1重定向并不重要。最重要的是,我们要问三通开/proc/self/fd/N在那里ñ已在使用。如果我们放弃了3>&1tee开始,我们应该得到相同的结果/proc/self/fd/2。让我们来看看:

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

已确认!结果相同。

我们也可以一遍又一遍地重复相同的fd数。达到fd 6时,我们得到的结果相同。到最后一个fd时,它已打开足够的描述符以使跳到6成为可能。

$ echo foo | tee /proc/self/fd/{2,2,2,2,6}
foo
foo
foo
foo
foo
foo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.