POSIX shell命令替换中的注释

8
我正在编写一个shell,但是无论是bash、dash还是busybox的ash都出现了意外的解析问题:
echo "`echo a #`"

输出a,但是

echo "$(echo a #)"

如果缺少一个闭合的),会产生有关缺失的错误。

根据POSIX规范,命令替换中的注释如何解析?因此,对于以下命令:

echo "`echo a #`"

并且

echo "$(echo a #)"

命令行解释器会将注释解析为扩展到命令替换的末尾,还是扩展到行末? 如果命令替换不在双引号内,命令行解释器是否会以不同方式解析它? 最后,是否有其他结构(在 POSIX 或 bash 中)可以在引号内开始注释?


1
kshzsh 表现出相同的行为。我没有解释,但这是 POSIX 规范相关部分的链接:http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html#tag_23_02_06_03 - mklement0
引用 # 可以避免它被视为注释字符的可能性,从而避免问题。 - chepner
@chepner,除非意图是为了文档目的在命令替换中添加注释,否则这里没有令人满意的答案。 - TamaMcGlinn
1
@TamaMcGlinn 命令替换可以跨多行进行。在 #) 之间加入新行即可。 - chepner
1个回答

7
根据Posix(Shell&Utilities,§2.6.3)的规定,"`echo a #`"未定义(意味着不应使用):

寻找匹配反引号的过程将由第一个未引用且未转义的反引号满足;在此搜索期间,如果遇到在shell注释中的未转义反引号,则会发生未定义的结果。(强调添加)

然而, $(命令替换标记是由“第一个匹配的”终止的;这意味着(通过Rationale的示例明确说明,注释、here-doc或引用字符串中不能有匹配的)

这个命令替换周围的引号在任何情况下都不相关(当然,如果引用了它们,则“未定义结果”可能因为它们是未定义的而不同)。

在bash和某些其他shell中,注释也可以存在于进程替换中(例如,<(…));但是,进程替换不能被引用。


注:

  1. 感谢@mklement0在评论中提供了此链接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接