多个标准输入?如何操作?

多个标准输入?如何操作?

由此命令行fu帖子

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

看起来像是多个标准输入,但如果我记得我的 Linux 编程课程没有错的话,这不可能。我认为,根据定义,标准输入是一个流。

也许这与 stdin 毫无关系?有人能给我解释一下吗?或者提供文档链接。

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

答案1

这不是多个标准输入。这是一种称为“进程替换”的 bash'ism 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 ]),这将要中断——这毕竟是作为命名管道实现的。

答案2

<(...)流程替代在 bash 中。括号中进程的输出被发送到正常的 3 个文件描述符之外的附加文件描述符,并返回与该文件描述符相对应的文件名。这样,命令的输出可以被视为要传递给另一个命令的文件名。

答案3

有一stdin,一stdout 对于每个过程。它们通常连接到终端,但可以彼此单独重定向。

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

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

其中连接到,stdout的连接到。wget -q -O - URL1/dev/fd/XXstdoutwget -q -O - URL2/dev/fd/YY

相关内容