多个标准输入?怎么样?


36

在此commandlinefu帖子中

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

似乎有多个标准输入,但是-如果我没记错我的Linux Porgramming课程-那就不可能了。我认为,按照定义,标准输入是一个流。

也许这与标准输入有关?谁可以给我解释一下这个; 也许提供文档链接。

好处:脚本将如何处理这些多个流?如果有人可以提供Python或Perl示例,那将非常有帮助。


1
好问题。如果您不知道,有一个unix / linux问答网站:unix.stackexchange.com
Matt Ellen 2010年


注意:在Bash中是<(…); 在Zsh进程中,替换语法为=(…)
卡米尔Maciorowski

Answers:


27

这不是多个标准输入。这是一种bash主义,称为“过程替代”,http://tldp.org/LDP/abs/html/process-sub.html

/dev/fd/something为每个替换创建一个伪文件()。非常有用 该命令只能作为流读取,这意味着它不能与fseek来回移动。它需要像管道一样将其读取为字节流。

奖励答案

您不需要做太多就可以使用它。就您的脚本而言,它会在命令行上获取一个有效的文件名,该文件名可以像其他任何文件一样打开()。正如其他人所说,您会看到的diff /dev/fd/XX /dev/fd/YY。如果对这些伪文件中的任何一个执行stat(),都会看到它是一个命名管道,并且应该使用管道语义来对待它-即没有fseek()或ftell()。如果您执行stat()测试以明确查看它是否是文件(例如[ -f $1 ]),则该文件中断-毕竟这是作为命名管道实现的。


bash进程替换的另一个很好的参考-wiki.bash-hackers.org/syntax/expansion/proc_subst
studgeek '17

以及此功能的建议用法是什么?只要您的程序可以合理地使用流而不需要具有随机访问权限的文件,就支持它吗?
masterxilo


7

每个过程都有一个stdin和一个。它们通常连接到终端,但是可以相互重定向。stdout

在该示例中,wget涉及两个过程,每个过程都有自己的stdinstdout。每个wget进程写入-,这是它stdout。然后bash的流程替换<(...)将流程的连接stdout到唯一的伪文件,该文件diff可以读取。请注意,这两个进程替换会产生两个不同的伪文件!因此,diff看到如下内容:

diff /dev/fd/XX /dev/fd/YY

其中stdoutwget -q -O - URL1连接到/dev/fd/XX,和所述stdoutwget -q -O - URL2/dev/fd/YY

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.