提问人:miken32 提问时间:11/20/2015 更新时间:11/20/2015 访问量:996
令人费解的 Bash 语法 -- 重定向到循环
Puzzling Bash syntax -- redirect into loop
问:
在运行脚本 shellcheck.net 时,我被告知“for
循环查找输出很脆弱”。公平地说,带有空格的文件名总是很棘手。
建议的替换代码(无论如何是其中之一)是这样的:
while IFS= read -r -d '' file
do
#do stuff
done < <(find . -name '*' -print0)
我熟悉用于将文本从文件输入到命令的运算符,显然结果被输入到循环中。因此,当我第一次看到这个时,我以为它是一些格式问题的受害者,并尝试“清理”最后一行。但是删除 之间的空格会导致语法错误,就像在 .<
find
< <
<(
那么这个结构在做什么呢?很抱歉,如果这是一个简单或多余的问题,搜索这些东西并不容易!< <(cmd)
答:
正如您所说,这是输入重定向。<
这是进程替换。<(
在支持命名管道 (FIFO) 或用于命名打开文件的 /dev/fd 方法的系统上支持进程替换。它采用以下形式
<(list)
或
>(list)
进程列表的输入或输出连接到 FIFO 或 /dev/fd 中的某个文件。作为扩展的结果,此文件的名称将作为参数传递给当前命令。如果使用 >(list) 形式,则写入文件将为 list 提供输入。如果使用 <(list) 形式,则应读取作为参数传递的文件以获取 list 的输出。请注意,<或>与左括号之间不能出现空格,否则构造将被解释为重定向。
如果可用,过程替换与参数和变量扩展、命令替换和算术扩展同时执行。
您不能将这两个标记组合在一起,因为这样就会成为此处文档标记。<
不能在 和 之间添加空格,因为这样它就不再是进程替换标记。<
(
评论
<(cmd)
echo <(echo foo)
cat <(echo foo)
循环输入是复合命令的一个示例。与任何其他命令一样,它有自己的标准输入。它实际上根本不会从中读取,但从循环中运行的任何命令都将从循环继承其标准输入。while
bash
while
在此示例中,该命令将从命令的输出中读取。read
find
<(find ...)
是流程替代的一个例子。该命令将运行,并且 被视为一个文件,其内容是命令的输出。循环(因此)正是这个“文件”用于其标准输入。find
<(...)
find
while
read
上一个:检查字符串的最后一个字符
评论