我试图在这个特定示例的上下文中理解命名管道。
我<(ls -l)
在终端中输入并得到输出,bash: /dev/fd/63: Permission denied
.
如果我输入cat <(ls -l)
,我可以看到目录内容。如果我用 替换cat
,echo
我想我会得到终端名称(或者是吗?)。
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
列出命令行上给出的文件和目录,我不相信它接受来自标准输入的任何输入。重定向>
>>
是<
使用文件提供输入和收集输出的方法。