【问题标题】:Nested double quotes in parameter expansion参数扩展中的嵌套双引号
【发布时间】:2021-11-12 13:54:17
【问题描述】:

我很惊讶以下是有效的Parameter Expansion。注意双引号中有未转义的双引号:

result="${var1#"$var2"}"

有人可以帮我解析一下吗?

【问题讨论】:

    标签: bash parameter-expansion


    【解决方案1】:

    在大括号中嵌套双引号是可以的。

    但在这种情况下,它们都不需要。

    result=${var1#$var2}
    

    即使对于包含空格和换行符的值也是如此。

    【讨论】:

    • 来自 POSIX 规范:“此外,可以使用以下格式之一修改参数扩展。在每种情况下,都需要 word 的值(基于参数的状态,如如下所述),单词应进行波浪号扩展、参数扩展、命令替换和算术扩展。”参数扩展被解析和评估引用的字符串,而不是被构造的引用字符串参数扩展。
    • 另外,手册文档的3.4 Shell Parameters 部分x 在变量赋值期间不执行分词和文件名扩展。这就是为什么 var=$value 中不需要引号的原因
    • 不过,引号实际上永远不会在此处造成任何伤害,并且可能值得包括只是为了防止某人花费大量时间追逐可能不会出现的问题任何。作为一种习惯,引号是你的朋友。如果您想真正友好,请使用引号说明它们为什么不是必需的注释。 ;)
    • @Roland 一般来说,没有。这取决于参数扩展发生的上下文。它确实发生在简单命令的参数位置的参数扩展的公共上下文中,但不是作为参数扩展运算符的参数,也不是在赋值的 RHS 上,也不是作为单词匹配case 语句等。
    • 它们被解析为花括号内的引号。
    【解决方案2】:

    答案是它们会被单独解析。让我们简单地浏览一下字符串。

    result="${var1#"$var2"}" 在这种情况下实际上不需要任何引号,但无论如何都要查看字符串...

    result="...
    

    解析器说嗯,这是一个任务,我知道如何处理这个,我会忽略这些,它们不会伤害任何东西,但现在我必须找到终止匹配。 然后它逐字节读取引号后的值,寻找终止双引号。这将启动一个新的 context-1。

    result="${...
    

    一旦它看到打开的花括号,它就知道在看到 匹配的 结束花括号之前不会出现终止引号。它启动了一个新的 context-2。

    result="${var1#"...
    

    在这个子上下文中看到一个新的双引号,使它成为内部 new context-3 的 开头 引号。

    result="${var1#"$var2"...
    

    当它看到这个双引号时,它将它与前一个匹配,关闭 context-3,回到 context-2。

    result="${var1#"$var2"}...
    

    这个关闭卷曲允许它关闭仍然打开的 context-2,回到 context-1。

    result="${var1#"$var2"}"
    

    找到这个现在关闭的双引号允许它关闭 context-1。以下换行符可以用作整个术语的终止字符,因此可以对其进行评估和分配。

    例如,反斜杠引用内部双引号会将它们添加到用于尾部修剪的字符串术语中,这可能会因此而失败。

    $: var1=aaa
    $: var2=a
    $: result="${var1#"$var2"}"
    $: echo $result                # does what you want/expect
    aa
    $: result="${var1#\"$var2\"}"  # does NOT
    $: echo $result
    aaa
    

    不带引号的情况下,解析器知道这是一个赋值,并且处理这些值的方式与 cmets 中提到的略有不同,但通常会像引用它们一样对待它们。

    $: result=${var1#$var2}
    $: echo $result
    aa
    

    这意味着它不必处理 context-1context-3,只需要担心卷曲。最终结果是一样的。

    更好?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 2013-03-05
      相关资源
      最近更新 更多