可以在字符串内插的任何嵌套构造都可以在其中包含其他字符串:它们像新脚本一样被解析,直到结束标记为止,甚至可以嵌套多层。所有这些酒吧之一都以开头$
。所有这些都在Bash手册和POSIX Shell命令语言规范的结合中进行了说明。
这些构造有几种情况:
找到的命令替换$( ... )
为。POSIX指定此行为:
使用该$(command)
格式,在开括号后面到匹配的闭括号后面的所有字符构成命令。任何有效的Shell脚本均可用于命令 ...
引号是有效的Shell脚本的一部分,因此可以使用其正常含义。
`
也使用命令替换。
高级参数替换实例(例如)${parameter:-word}
的“ word”元素。“单词”的定义是:
外壳将一个字符序列视为一个单元
-包括加引号的文字,甚至是混合的引号a"b"c'd'e
-尽管扩展程序的实际行为比这种情况更为宽松,例如${x:-hello world}
也可以。
算术扩展用$(( ... ))
,虽然它在很大程度上是无用的存在(但你可以嵌套命令替换或变量的扩张,也再有引号里面有用的)。POSIX指出:
表达式应被视为双引号,除非表达式内的双引号未特别处理。外壳程序应扩展表达式中的所有标记,以进行参数扩展,命令替换和引用删除。
因此,此行为是明确需要的。那意味着echo "abc $((4 "*" 5))"
算术,而不是遍历。
不过,请注意旧式$[ ... ]
算术扩展不以相同方式处理:如果它们出现的报价将是一个错误,不管扩张引述与否。此表格已不再记录,也无意使用。
- 带有的特定于语言环境的翻译
$"..."
,实际上使用"
作为核心元素。$"
被视为一个单元。
您可能不会想到还有另一种嵌套情况,即不涉及引号,这是通过大括号扩展:{a,b{c,d},e}
扩展为“ a bc bd e”。${x:-a{b,c}d}
确实没有然而窝; 它被视为参数替换,给出“ a{b,c
”,后跟“ d}
”。这也有记载:
使用花括号时,匹配的结尾花括号是第一个'}',不会被反斜杠或加引号的字符串引起,也不会位于嵌入式算术扩展,命令替换或参数扩展之内。
通常,所有带分隔符的构造都独立于周围的上下文来解析其主体(并且异常被视为bug)。从本质上说,在看到$(
命令替换的代码只是要求解析器从身体消耗所能,就好像它是一个新的程序,然后检查,预期结束标志(一个转义)
或))
或}
)出现一次子解析器运行消耗掉的东西。
如果您考虑递归下降解析器的功能,那只是对基本情况的简单递归。一旦您完成了字符串插值,实际上比其他方法更容易实现。不管底层的解析技术如何,支持这些构造的shell都会产生相同的结果。
通过这些结构,您可以根据需要嵌套最深的引用,并且它将按预期工作。在中间看到报价,不会让任何地方感到困惑。相反,这将是内部上下文中新的带引号的字符串的开始。