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

时间:2015-11-19 19:25:35

标签: bash syntax io-redirection

通过shellcheck.net运行脚本我被告知"for loops over find output are fragile."很公平,带空格的文件名总是很棘手。

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

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

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

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

2 个答案:

答案 0 :(得分:5)

正如您所说,<input redirection

<(Process Substitution

  

支持命名管道(FIFO)的系统或命名打开文件的/ dev / fd方法支持进程替换。它采取

的形式
<(list)
     

>(list)
     

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

     

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

您无法合并两个<标记,因为这会成为here document标记。

您无法在<(之间添加空格,因为它会停止作为流程替换令牌。

答案 1 :(得分:3)

while中的bash循环是复合命令的示例。像任何其他命令一样,它有自己的标准输入。它根本没有从中读取,但是从while循环内运行的任何命令都将继承循环中的标准输入。

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

<(find ...)流程替换的示例。运行find命令,<(...)被视为文件,其内容是find命令的输出。这是&#34;文件&#34; while循环(因此read)用于其标准输入。