令人费解的 Bash 语法——重定向到循环
Puzzling Bash syntax -- redirect into loop
运行 通过 shellcheck.net 的脚本有人告诉我 "for
loops over find
output are fragile." 很公平,带空格的文件名总是很棘手。
建议的替换代码(其中之一)是这样的:
while IFS= read -r -d '' file
do
#do stuff
done < <(find . -name '*' -print0)
我熟悉用于将文本从文件输入到命令的 <
运算符,显然 find
的结果被送入循环。因此,当我第一次看到它时,我认为它是某些格式问题的受害者,并尝试 "cleaning up" 最后一行。但是删除 < <
之间的空格会导致语法错误,在 <(
.
中添加一个也是如此
那么 < <(cmd)
结构在做什么?很抱歉,如果这是一个简单或多余的问题,搜索这些东西并不容易!
你说的<
就是input redirection
<(
是 Process Substitution。
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. It takes the form of
<(list)
or
>(list)
The process list is run with its input or output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list. Note that no space may appear between the < or > and the left parenthesis, otherwise the construct would be interpreted as a redirection.
When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.
您不能将两个 <
标记组合起来,因为这样就变成了 here document 标记。
您不能在 <
和 (
之间添加 space,因为这样它就不再是进程替换标记。
bash
中的 while
循环是复合命令的示例。与任何其他命令一样,它有自己的标准输入。它实际上根本不从中读取,但是 while
循环中的任何命令 运行 将从循环中继承其标准输入。
在此示例中,read
命令将从 find
命令的输出中读取。
<(find ...)
是 进程替换 的示例。 find
命令是 运行,<(...)
被视为一个文件,其内容是 find
命令的输出。 while
循环(因此 read
)使用的正是这个 "file" 作为标准输入。
运行 通过 shellcheck.net 的脚本有人告诉我 "for
loops over find
output are fragile." 很公平,带空格的文件名总是很棘手。
建议的替换代码(其中之一)是这样的:
while IFS= read -r -d '' file
do
#do stuff
done < <(find . -name '*' -print0)
我熟悉用于将文本从文件输入到命令的 <
运算符,显然 find
的结果被送入循环。因此,当我第一次看到它时,我认为它是某些格式问题的受害者,并尝试 "cleaning up" 最后一行。但是删除 < <
之间的空格会导致语法错误,在 <(
.
那么 < <(cmd)
结构在做什么?很抱歉,如果这是一个简单或多余的问题,搜索这些东西并不容易!
你说的<
就是input redirection
<(
是 Process Substitution。
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. It takes the form of
<(list)
or
>(list)
The process list is run with its input or output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list. Note that no space may appear between the < or > and the left parenthesis, otherwise the construct would be interpreted as a redirection.
When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.
您不能将两个 <
标记组合起来,因为这样就变成了 here document 标记。
您不能在 <
和 (
之间添加 space,因为这样它就不再是进程替换标记。
bash
中的 while
循环是复合命令的示例。与任何其他命令一样,它有自己的标准输入。它实际上根本不从中读取,但是 while
循环中的任何命令 运行 将从循环中继承其标准输入。
在此示例中,read
命令将从 find
命令的输出中读取。
<(find ...)
是 进程替换 的示例。 find
命令是 运行,<(...)
被视为一个文件,其内容是 find
命令的输出。 while
循环(因此 read
)使用的正是这个 "file" 作为标准输入。