2015-11-19 115 views
4

通过shellcheck.net运行脚本我被告知"for loops over find output are fragile."足够公平,带空格的文件名总是很棘手。令人困惑的Bash语法 - 重定向到循环

建议的替换代码(反正是其中之一)是这样的:

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

我所熟悉的用于输入文本,从文件到命令<运营商,并明确从find结果被喂入循环。所以,当我第一次看到这个,我认为这是受害者一些格式化的问题,并试图“清理”的最后一行。但是,消除< <之间的空白导致语法错误一样,增加一个到<(

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

回答

5

如您所说,<input redirection

<(Process Substitution

进程替换被支撑在支持命名管道(FIFO)或命名打开的文件的的/ dev/FD方法的系统。它需要的

<(list) 

>(list) 

进程列表的形式与它的输入或输出连接到一个FIFO或在的/ dev/FD一些文件中运行。作为扩展的结果,此文件的名称作为参数传递给当前命令。如果使用>(列表)表单,写入文件将为列表提供输入。如果使用了<(列表)的形式,作为一个参数传递的文件应该被读取以获得列表的输出。请注意,没有空间可以在<或>和左括号之间出现,否则结构将被解释为一个重定向。

如果可用,与参数和变量扩展,命令替换和算术扩展同时进行处理替代。

因为那么它将成为一个here document令牌不能将二者结合起来<马克。

您不能在<(之间添加空格,因为它不再是进程替换令牌。

+0

明白了;所以命令的输出被发送到一个文件描述符,并且'<(cmd)'语句被扩展为该文件描述符名称。 (现在我有一个术语来搜索是否需要更多信息!) – miken32

+0

是的。例如,请参阅'echo <(echo foo)'和'cat <(echo foo)'。 –

3

A while循环bash是复合命令的一个例子。像其他命令一样,它有自己的标准输入。它实际上并没有从中读取可言,但是从while环路内的任何命令运行时会从循环继承它的标准输入。

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


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