为什么进程替换会产生一个名为 /dev/fd/63 的文件,该文件是一个管道?

为什么进程替换会产生一个名为 /dev/fd/63 的文件,该文件是一个管道?

我试图在这个特定示例的上下文中理解命名管道。

<(ls -l)在终端中输入并得到输出,bash: /dev/fd/63: Permission denied.

如果我输入cat <(ls -l),我可以看到目录内容。如果我用 替换catecho我想我会得到终端名称(或者是吗?)。

echo <(ls -l)给出输出为/dev/fd/63.

另外,这个示例输出对我来说不清楚。

ls -l <(echo "Whatever")
lr-x------ 1 root root 64 Sep 17 13:18 /dev/fd/63 -> pipe:[48078752]

但是,如果我给出,ls -l <()它会列出目录内容。

如果使用命名管道,会发生什么情况?

答案1

当您这样做时<(some_command),您的 shell 会执行括号内的命令,并将整个内容替换为连接到命令的标准输出的文件描述符。/dev/fd/63包含 ls 调用输出的管道也是如此。

当你这样做时,<(ls -l)你会得到一个Permission denied错误,因为整行都被管道替换,有效地尝试/dev/fd/63作为命令调用,这是不可执行的。

在你的第二个例子中,cat <(ls -l)变成cat /dev/fd/63.当 cat 从作为参数给出的文件中读取时,您将获得内容。echo另一方面,只是“按原样”输出其参数。

最后一个案例<()只是被什么都替换了,因为没有命令。但这在 shell 之间并不一致,在 zsh 中你仍然会得到一个管道(尽管是空的)。

概括<(command)允许您使用命令的输出,而您通常需要文件。

编辑:作为吉尔斯指出,这不是命名管道,而是匿名管道。主要区别在于,只要进程正在运行,它就存在,而命名管道(例如使用 创建的mkfifo)将保持不变,而不会附加任何进程。

答案2

您误解了ls命令和重定向。ls列出命令行上给出的文件和目录,我不相信它接受来自标准输入的任何输入。重定向> >><使用文件提供输入和收集输出的方法。

相关内容