令人费解的 Bash 语法 -- 重定向到循环

Puzzling Bash syntax -- redirect into loop

提问人:miken32 提问时间:11/20/2015 更新时间:11/20/2015 访问量:996

问:

在运行脚本 shellcheck.net 时,我被告知for 循环查找输出很脆弱”。公平地说,带有空格的文件名总是很棘手。

建议的替换代码(无论如何是其中之一)是这样的:

while IFS= read -r -d '' file
do
    #do stuff
done <   <(find . -name '*' -print0)

我熟悉用于将文本从文件输入到命令的运算符,显然结果被输入到循环中。因此,当我第一次看到这个时,我以为它是一些格式问题的受害者,并尝试“清理”最后一行。但是删除 之间的空格会导致语法错误,就像在 .<find< <<(

那么这个结构在做什么呢?很抱歉,如果这是一个简单或多余的问题,搜索这些东西并不容易!< <(cmd)

bash 语法 io-redirection

评论


答:

5赞 Etan Reisner 11/20/2015 #1

正如您所说,这是输入重定向<

这是进程替换<(

在支持命名管道 (FIFO) 或用于命名打开文件的 /dev/fd 方法的系统上支持进程替换。它采用以下形式

<(list)

>(list)

进程列表的输入或输出连接到 FIFO 或 /dev/fd 中的某个文件。作为扩展的结果,此文件的名称将作为参数传递给当前命令。如果使用 >(list) 形式,则写入文件将为 list 提供输入。如果使用 <(list) 形式,则应读取作为参数传递的文件以获取 list 的输出。请注意,<或>与左括号之间不能出现空格,否则构造将被解释为重定向。

如果可用,过程替换与参数和变量扩展、命令替换和算术扩展同时执行。

您不能将这两个标记组合在一起,因为这样就会成为此处文档标记。<

不能在 和 之间添加空格,因为这样它就不再是进程替换标记。<(

评论

0赞 miken32 11/20/2015
明白了;因此,命令的输出将发送到文件描述符,并将语句扩展为该文件描述符名称。(现在,如果我需要更多信息,我有一个术语可以搜索!<(cmd)
0赞 Etan Reisner 11/20/2015
是的。请参阅和示例。echo <(echo foo)cat <(echo foo)
3赞 chepner 11/20/2015 #2

循环输入是复合命令的一个示例。与任何其他命令一样,它有自己的标准输入。它实际上根本不会从中读取,但从循环中运行的任何命令都将从循环继承其标准输入。whilebashwhile

在此示例中,该命令将从命令的输出中读取。readfind


<(find ...)流程替代的一个例子。该命令将运行,并且 被视为一个文件,其内容是命令的输出。循环(因此)正是这个“文件”用于其标准输入。find<(...)findwhileread