【问题标题】:Puzzling Bash syntax -- redirect into loop令人费解的 Bash 语法——重定向到循环
【发布时间】:2015-11-19 19:25:35
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: bash syntax io-redirection


    【解决方案1】:

    如你所说,&lt;input redirection

    &lt;(Process Substitution

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

    <(list)
    

    >(list)
    

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

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

    您不能将两个 &lt; 标记组合起来,因为那样会变成 here document 标记。

    您不能在 &lt;( 之间添加空格,因为这样它就不再是进程替换标记了。

    【讨论】:

    • 知道了;因此命令的输出被发送到文件描述符,&lt;(cmd) 语句被扩展为该文件描述符名称。 (如果我需要更多信息,现在我可以搜索一个术语!)
    • 是的。例如,请参阅 echo &lt;(echo foo)cat &lt;(echo foo)
    【解决方案2】:

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

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


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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 2020-10-06
      相关资源
      最近更新 更多