简体   繁体   English

为什么反引号中的嵌套引号在bash中有效?

[英]Why does nesting quotes in backticks work in bash?

More precisely, why does 更确切地说,为什么

"`command "$variable"`"

treat the outer quotes as enclosing the inner quotes, instead of expanding the variable outside any quotes? 将外部引号视为封闭内部引号,而不是将变量扩展到任何引号之外?

The exact command I used to test this is similar to an example brought up in another stackoverflow question about the correct method of quoting when using command substitution: 我用于测试此命令的确切命令类似于另一个stackoverflow问题中提出的有关使用命令替换时引用正确方法的示例:

fileName="some path with/spaces"
echo "`dirname "$fileName"`"

which correctly echoes "some path with", instead of complaining because of an invalid number of arguments. 它正确地回显了“某些路径”,而不是因为参数数量无效而抱怨。

I read Bash's man page, where it states in chapter "EXPANSION", section "Commmand Substitution" that the new-style $() substitution preserves the meaning of any character between the parentheses, however, regarding backquotes, it only mentions that backslashes work in a limited way: 我阅读了Bash的手册页,其中在“扩展”一章的“命令替换”部分中指出,新型$()替换保留了括号之间任何字符的含义,但是,对于反引号,它仅提及反斜杠有效以有限的方式:

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $ , ` , or \\ . 当使用旧式的反引号形式的替换时,反斜杠保留其字面意思,除非后面是$`\\ The first backquote not preceded by a backslash terminates the command substitution. 没有反斜杠的第一个反引号将终止命令替换。

My first thought was that backticks do the same, aside from the mentioned exception, thus "quoting" the inner double quotes, however, I got told that is not the case. 我首先想到的是,除了提到的例外情况外,反引号也是如此,因此“引用”了内部的双引号,但是,我被告知并非如此。 The second observation that pointed me to this direction was that 向我指出这一方向的第二个观察是

a=\$b
b=hello
echo `echo $a`

prints "$b". 打印“ $ b”。 Had the backticks let the dollar sign get interpreted, the first variable substitution should have occurred before the subshell was invoked, with the subshell expanding the string "$b", resulting in "hello." 如果反引号使美元符号得到解释,则第一个变量替换应该在调用子外壳程序之前发生,并且子外壳程序将字符串“ $ b”扩展为“ hello”。 According to the above excerpt from the man page, I can even make sure the dollar sign is actually quoted, by using 根据手册页中的上述摘录,我什至可以通过使用来确保美元符号确实被引用了

echo `echo \$a`

and the results would still be the same. 结果仍然是一样的。

A third observation gives me some doubts though: 第三个观察结果给了我一些疑问:

 echo `echo \\\\a` 

Result: "\\a" 结果:“ \\ a”

 echo \\a 

Result: a 结果:

Here it seems like both backslashes were retained until the subshell came into play, even though the man page states that backslashes within backquotes do not have their literal meaning when followed by another backslash. 在这里,似乎两个反斜杠都一直保留到子shell起作用为止,即使手册页指出反斜杠中的反斜杠在后面加上另一个反斜杠时也没有字面意义。 EDIT: ^ Everything works as expected in this regard, I must have used the wrong shell (tcsh in my other terminal, and with a different character from "a"). 编辑:^在这方面一切都按预期工作,我必须使用了错误的外壳程序(在我的其他终端中为tcsh,并且字符与“ a”不同)。

Although I have not been able to find out what actually happens, while I was searching for the answer, I came across some people mentioning the term "quoting context" with regards to command substitution, but without any explanation as to what it means or where it is described. 尽管我无法找出实际发生的情况,但是在寻找答案时,我遇到了一些人在提及命令替换时提到“引用上下文”一词,但是却没有任何含义或解释。它被描述。 I have not found any real reference to "quoting contexts" in either Bash references (gnu.org, tldp, man bash) or via DuckDuckGo. 我在Bash引用(gnu.org,tldp,man bash)或通过DuckDuckGo中都没有找到对“引用上下文”的任何真正引用。

Additionally to knowing what is going on, I'd preferably like to have some reference or guidance as to how this behavior can be discerned from it, because I think I might have failed to put some pieces together from which this naturally comes. 除了了解正在发生的事情之外,我还希望对如何识别这种行为有一些参考或指导,因为我认为我可能无法将某些东西自然地融合在一起。 Otherwise I'll just forget the answer. 否则,我只会忘记答案。

To those recommending people to use the new-style dollar sign and parentheses substitution: on ca. 对于那些建议人们使用新型美元符号和括号替换的人: 50 years old Unix machines with tens or hundreds of different proprietary environments (can't throw out a shell for a newer one), when one has to write scripts compatible between most shells that anyone might be using, it is not an option. 50年历史的Unix计算机拥有数十种或数百种不同的专有环境(不能为新的环境扔掉一个外壳),当一个人必须编写任何人都可能使用的大多数外壳之间兼容的脚本时,这不是一种选择。

Thanks to anyone who can help me. 感谢任何可以帮助我的人。

POSIX has this to say in 2.2.3 (emphasis mine): POSIX在2.2.3(强调我的)中有这样的说法:

` (backquote) `(反引号)

The backquote shall retain its special meaning introducing the other form of command substitution (see Command Substitution). 反引号应保留其特殊含义,引入另一种形式的命令替换(请参阅命令替换)。 The portion of the quoted string from the initial backquote and the characters up to the next backquote that is not preceded by a <backslash>, having escape characters removed, defines that command whose output replaces "`...`" when the word is expanded. 引号字符串从初始反引号和直到下一个反引号的字符之前没有<backslash>的部分(已删除转义字符) 定义了该命令 ,当单词为时,该命令的输出将替换为“`...`”扩展。 Either of the following cases produces undefined results: 以下两种情况均会产生不确定的结果:

  • A single-quoted or double-quoted string that begins, but does not end, within the "`...`" sequence 在“`...`”序列中开始但不结束的单引号或双引号字符串

  • A "`...`" sequence that begins, but does not end, within the same double-quoted string 在相同的双引号字符串中开始但不结束的“`...`”序列

This, to me, pretty much defines what other people might (informally?) call a quoting context comprising everything within two consecutive backquotes. 对我来说,这几乎定义了其他人(非正式地?)可以称为包含两个连续反引号中的所有内容的报价上下文

In a way, the backquote is the fourth quote in addition to single quote, double quote and backslash. 在某种程度上,除了单引号,双引号和反斜杠之外,反引号是第四引号。 Note that within double quotes, single quotes lose their quoting capability as well, so it should be no surprise that backquotes change the function of double quotes within them. 请注意,在双引号中,单引号也失去了引号功能,因此反引号会更改其中的双引号功能也就不足为奇了。

I tried your example with other shells, like the Almquist shell on FreeBSD and zsh. 我尝试了其他shell的示例,例如FreeBSD和zsh上的Almquist shell。 As expected, they output some path with . 如预期的那样,它们使用输出了some path with

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM