更准确地说,为什么
"`command "$variable"`"
将外部引号视为包含内部引号,而不是将变量扩展到任何引号之外?
我用来测试这个的确切命令类似于另一个 stackoverflow 问题中提出的关于使用命令替换时正确引用方法的示例:
fileName="some path with/spaces"
echo "`dirname "$fileName"`"
它正确地呼应了“some path with”,而不是因为参数数量无效而抱怨。
我阅读了 Bash 的手册页,其中在“扩展”一章的“命令替换”部分中指出,新型 $() 替换保留了括号之间任何字符的含义,但是,关于反引号,它只提到反斜杠有效以有限的方式:
当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后面跟着
$
,`
或\
。前面没有反斜杠的第一个反引号终止命令替换。
我的第一个想法是反引号也一样,除了提到的例外,因此“引用”内部双引号,但是,我被告知事实并非如此。指出我这个方向的第二个观察是
a=\$b
b=hello
echo `echo $a`
打印“$b”。如果反引号让美元符号得到解释,那么第一个变量替换应该在调用子shell之前发生,子shell扩展字符串“$b”,结果是“hello”。根据手册页的上述摘录,我什至可以通过使用确保美元符号实际被引用
echo `echo \$a`
结果仍然是一样的。
第三个观察结果让我有些怀疑:
echo `echo \\a`
结果:“\a”
echo \a
结果:一个
在这里,似乎两个反斜杠都被保留了,直到 subshell 发挥作用,即使手册页指出反引号中的反斜杠在后面跟着另一个反斜杠时没有其字面意义。编辑: ^ 在这方面一切都按预期工作,我一定使用了错误的 shell(我的另一个终端中的 tcsh,并且字符与“a”不同)。
虽然我无法找出实际发生的情况,但在我寻找答案时,我遇到一些人提到关于命令替换的术语“引用上下文”,但没有任何解释它的含义或位置它被描述。我在 Bash 引用(gnu.org、tldp、man bash)或通过 DuckDuckGo 中都没有找到对“引用上下文”的任何真正引用。
除了了解正在发生的事情之外,我更希望获得一些关于如何从中辨别这种行为的参考或指导,因为我认为我可能未能将一些部分放在一起,而这些部分是自然产生的。否则我会忘记答案。
对于那些建议人们使用新式美元符号和括号替换的人:在 ca。具有数十或数百种不同专有环境的 50 年历史的 Unix 机器(不能为更新的环境丢弃 shell),当必须编写与大多数人可能使用的 shell 兼容的脚本时,这不是一种选择。
感谢任何可以帮助我的人。