ogu*_*ail 29 linux bash shell io-redirection proc-filesystem
我希望
echo foo | tee /proc/self/fd/{3..6} 3>&1
Run Code Online (Sandbox Code Playgroud)
因/ proc / self / fd / 4之类的错误而失败:没有这样的文件或目录等,但令我惊讶的是,它输出
foo
foo
foo
foo
foo
Run Code Online (Sandbox Code Playgroud)
就像3>&1
导致以下所有描述符都重定向到stdout一样,除非如果我更改3
为其他内容则不起作用,例如
echo foo | tee /proc/self/fd/{3..6} 3>&1
Run Code Online (Sandbox Code Playgroud)
有这种行为的解释吗?
Joh*_*ica 29
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
...
Run Code Online (Sandbox Code Playgroud)
第一行打开,/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的副本。
请注意,3>&1
重定向并不重要。最重要的是,我们要问三通开/proc/self/fd/N
在那里ñ已在使用。如果我们放弃了3>&1
tee开始,我们应该得到相同的结果/proc/self/fd/2
。让我们来看看:
$ echo foo | tee /proc/self/fd/{2..6}
foo
foo
foo
foo
foo
foo
Run Code Online (Sandbox Code Playgroud)
已确认!结果相同。
我们也可以一遍又一遍地重复相同的fd数。达到fd 6时,我们得到的结果相同。到最后一个fd时,它已经打开了足够的描述符以使跳到6成为可能。
$ echo foo | tee /proc/self/fd/{2,2,2,2,6}
foo
foo
foo
foo
foo
foo
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1187 次 |
最近记录: |