【发布时间】:2019-01-07 18:16:51
【问题描述】:
背景
POSIX Shell 命令语言允许重定向遵循 compound 命令。 standard 说(强调我的)
2.9.4 复合命令
shell 有几个编程结构,它们是“复合命令”,它们为命令提供控制流。这些复合命令中的每一个在开头都有一个保留字或控制运算符,在末尾有一个相应的终止符保留字或运算符。此外,每个都可以跟在与终止符相同的行上的重定向。每个重定向都应适用于复合命令中未明确覆盖该重定向的所有命令。
出于美学原因,我想在我的while循环之前放置一个heredoc
<<'RECORDS' while
foo:bar
baz:quux
...
RECORDS
IFS=: read -r A B
do
# do something with A and B
done
因为它使代码更容易理解。但是,它在我尝试过的 shell 中不起作用(bash 和 dash)。我收到错误提示找不到“while”命令,我认为这意味着在领先的 heredoc 之后需要一个 simple 命令而不是 compound 命令。
我无法将heredoc 移动到read 之后,因为它会在每次迭代时从新的heredoc 中读取第一行。我知道我可以通过将heredoc 移到done 之后来解决这个问题。我还可以在循环之前使用exec 打开一个指向heredoc 的fd,并添加一个到read 的重定向。
我的问题
在复合命令之前不能发生重定向的原因是什么?由于 POSIX 没有明确禁止,是否有支持它的 shell?
【问题讨论】:
-
“它使代码更容易理解”。这是主观的,充其量是。
-
@chepner 确实!这就是我提出这个问题的原因,但我要求澄清这个看似任意的 shell 限制。
-
有时基本原理只是现有行为。如果大多数现有的 shell 实现在复合命令之前禁止重定向,则规范没有理由强制执行新行为。 (我不知道真正的原因,因此发表了此评论。也许有技术原因导致解析此类结构非常困难,尽管我无法想象它会比解析实际语法困难得多。)
标签: shell while-loop sh posix heredoc