/dev/stdout
我知道人们经常可以通过传递文件名来欺骗期望文件通过管道传输到标准输出的命令行实用程序。
我想知道是否可以将工具管道设置为编号文件描述符而不是stdout
/ stderr
,就像我可以执行以下操作来管道stderr
而不是stdout
:
command 2>&1 >/dev/null | grep 'something'
为了使我的问题更加具体(最小可重现的示例):我需要在这里替换什么/dev/stdout
,以便输出最终出现在文件描述符编号 3 中,而不是stdout
(我不是问有关任何特定工具的问题,我想知道什么)用于通过管道传输到 fd 3 的字符串,因为我可以使用/dev/stdout
.
cp a /dev/stdout
替换cp
为通常需要文件路径的命令。
有效吗/dev/3
?我正在寻找/dev/stdout
fd 3 而不是 fd 1 的类似物。
用另一种方式重新表述这个问题:
file descriptor 1 is to /dev/stdout
what
file descriptor 3 is to ???
我应该在这里使用什么而不是???
我搜索得很广泛但找不到任何东西。
答案1
在许多系统(不是全部!)上,/dev/fd/
是文件句柄的目录。在 Linux 上,它通常是 的链接/proc/self/fd
,但在 NetBSD9(例如)上,它是一个实际目录。
所以
% ( cat a > /dev/fd/9) 9>&1 >/dev/null | grep .
foo
但是,cp
似乎取决于您使用的外壳。
在带有 ksh93 的 CentOS7 上...
% cp a /dev/fd/9 9>&1 >/dev/null | cat
cp: cannot create regular file '/dev/fd/9': No such device or address
那是因为/dev/fd/9
这不是一个常规文件。但随着bash
...
$ cp a /dev/fd/9 9>&1 >/dev/null | cat
foo
有效!
我们可以看到,这并不能保证在所有平台上都存在,并且不可移植,即使在同一平台上的 shell 之间也是如此!
答案2
据我所知并非在所有系统上。但是,在 Debian 甚至所有 Gnu/Linux 上
/dev/stdout
是到 的符号链接/proc/self/fd/1
。如果我们查看目录/proc/self/fd/
,那么我们会找到其他文件描述符。请注意,此处仅包含正在使用的文件描述符。这将取决于过程。
答案3
尝试/proc/self/fd/«number»
您实际上可以通过命名进程 ID 这种方式访问任何进程文件。
这是特定于操作系统的,可能不适用于所有 Unix。