【问题标题】:POSIX shell comments in command-substitutions命令替换中的 POSIX shell 注释
【发布时间】:2017-10-04 13:54:54
【问题描述】:

我正在编写一个 shell,并且从 bash、dash 和 busybox 的 ash 中得到了意想不到的解析:

echo "`echo a #`"

打印a,但是

echo "$(echo a #)"

给出一个关于缺少结束 ) 的错误。

如何根据 POSIX 解析命令替换中的注释? 所以,对于命令:

echo "`echo a #`"

echo "$(echo a #)"

shell 会将注释解析为延伸到命令替换的末尾还是行尾? 此外,如果命令替换不在双引号中,shell 会以不同的方式解析它吗? 最后,是否有任何其他结构(在 POSIX 或 bash 中)可以在这样的引号内开始注释?

【问题讨论】:

  • kshzsh 表现出相同的行为。我没有解释,但这里是 POSIX 规范相关部分的链接:pubs.opengroup.org/onlinepubs/9699919799/xrat/…
  • 引用# 以避免它被视为注释字符的任何可能性将避免该问题。
  • @chepner 除非目的是在命令替换中添加注释以用于文档目的 - 在这种情况下,这里没有令人满意的答案。
  • @TamaMcGlinn 命令替换可以分成多行。在#) 之间添加一个换行符。

标签: bash sh posix language-lawyer busybox


【解决方案1】:

根据 Posix (Shell&Utilities, §2.6.3),"`echo a #`" 是未定义的(暗示不应该使用它):

对匹配反引号的搜索应由第一个未引用的非转义反引号来满足;在此搜索过程中,如果在 shell 注释中 遇到非转义的反引号,... 会出现未定义的结果。 (强调)

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

命令替换周围的引号在这两种情况下都不相关(当然,“未定义的结果”在引用的情况下可能会有所不同,因为它们是未定义的。)

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


注意事项:

  1. 感谢@mklement0,他将此链接包含在评论中。

【讨论】:

    猜你喜欢
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多