简体   繁体   English

Bash解析和shell扩展

[英]Bash parsing and shell expansion

I'm confused in the way bash parses input and performs expansion. 我对bash解析输入和执行扩展的方式感到困惑。

For input say, \\'"\\"hello world\\"" passed as argument in bash to a script that displays what its input is, I'm not exactly sure how Bash parses it. 对于输入说, \\'"\\"hello world\\""作为参数在bash中传递给显示其输入的脚本,我不确定Bash如何解析它。

Example, 例,

var=\'"\"hello   world\""
./displaywhatiget.sh "$var"
I got '"hello   world"

I understand that the double quotes in "$var" tells bash to treat the value of var together. 据我所知, "$var"中的双引号告诉bash将var的值一起处理。 However, what I don't understand is when is the backslash escaping and double-quoted parsing for the value takes place in bash's expansion process. 但是,我不明白的是反斜杠何时转义,并且在bash的扩展过程中对值进行双引号解析。

I'm coming from shell-operation , and shell expansion . 我来自shell操作shell扩展

All of the interesting things happen in the assignment, var=\\'"\\"hello world\\"" . 所有有趣的事情都发生在赋值中, var=\\'"\\"hello world\\"" Let's break it down: 让我们分解一下:

  • \\' - this is an escaped single-quote. \\' - 这是一个逃脱的单引号。 Without the escape, it would start a single-quoted string, but escaped it's just a literal single-quote. 没有逃脱,它将启动一个单引号字符串,但逃脱它只是一个字面单引号。 Thus, the final string will start with ' . 因此,最后的字符串将以'开头。
  • " - this starts a double-quoted string. " - 这会启动一个双引号字符串。
  • \\" - an escaped double-quote; like the escaped single-quote, this gets treated as a literal double-quote, so " will be the second character of the final string. \\" - 一个转义的双引号;就像转义的单引号一样,这被视为文字双引号,所以"将是最后一个字符串的第二个字符。
  • hello world - since we're still in a double-quoted string, this just gets included literally in the final string. hello world - 因为我们仍然是一个双引号字符串,这只是字面上包含在最后的字符串中。 Note that if we weren't in double-quotes at this point, the space would've marked the end of the string. 请注意,如果此时我们不是双引号,则空格将标记字符串的结尾。
  • \\" - another escaped double-quote; again, included literally so the last character of the final string will be " . \\" - 另一个转义的双引号;再次,字面上包括所以最终字符串的最后一个字符将是"
  • " - this closes the double-quoted string. " - 这会关闭双引号字符串。

Thus, var gets assigned the value '"hello world" . 因此, var被赋值为'"hello world" In ./displaywhatiget.sh "$var" , the double-quotes mean that $var gets replaced by var 's value, but no further interpretation is done; ./displaywhatiget.sh "$var" ,双引号表示$varvar的值替换,但没有进一步的解释; that's just passed directly to the script. 这只是直接传递给脚本。

UPDATE: When using set -vx , bash prints the assignment in a somewhat strange way. 更新:当使用set -vx ,bash以一种有点奇怪的方式打印赋值。 As I said in a comment, what it does is take the original command, parse it (as I described above) to figure out what it means, then back-translate that to get an equivalent command (ie one that'd have the same effect). 正如我在评论中所说,它所做的是采用原始命令,解析它(如上所述)来弄清楚它的含义,然后反向转换它以获得一个等效命令(即具有相同命令的命令)影响)。 The equivalent command it comes up with is var=''\\''"hello world"' . 它提出的等效命令是var=''\\''"hello world"' Here's how that would be parsed: 以下是解析的方法:

  • '' - this is a zero-length single-quoted string; '' - 这是一个零长度的单引号字符串; it has no effect whatsoever. 它没有任何效果。 I'm not sure why bash includes it. 我不确定为什么bash包含它。 I'm tempted to call it a bug, but it's not actually wrong , just completely pointless. 我很想把它称为一个bug,但它实际上并没有 ,只是毫无意义。 BTW, if you want an example of quote removal, here it is: in this command, these quotes would just be removed with no trace left. 顺便说一句,如果你想要一个引用删除的例子,这里是:在这个命令中,这些引号将被删除而没有留下痕迹。
  • \\' - this is an escaped single-quote, just like in the original command. \\' - 这是一个转义的单引号,就像在原始命令中一样。 The final string will start with ' . 最后一个字符串将以'开头。
  • ' - this starts a single-quoted string. ' - 这会启动一个单引号字符串。 No interpretation at all is performed inside single-quotes, except for looking for the close-quote. 除了寻找close-quote之外,单引号内部没有任何解释。
  • "hello world" - since we're in a single-quoted string, this just gets included literally in the final string, including the double-quotes and space. "hello world" - 因为我们在一个单引号字符串中,这只是字面上包含在最后的字符串中, 包括双引号和空格。
  • ' - this closes the single-quoted string. ' - 这会关闭单引号字符串。

so it gets the same value assigned to var , just written differently. 所以它获得了分配给var的相同值,只是用不同的方式写的。 Any of these would also have the same effect: 任何这些也会产生同样的效果:

var=\''"hello world"'
var="'\"hello world\""
var=\'\"hello\ world\"
var="'"'"hello world"'
var=$'\'"hello world"'

...and many others. ......还有很多其他人。 bash could technically have printed any of these under set -vx . bash在技术上可以在set -vx下打印任何这些。

The parsing of the \\ -prefixed escape sequences happens on assignment : \\ -prefixed转义序列的解析在赋值时发生:

var=\'"\"hello   world\""

causes Bash to store the following literal in $var : '"hello world" . 导致Bash在$var'"hello world"存储以下文字。

On later referencing $var inside a double-quoted string ( "$var" ) the above literal becomes a literal part of that double-quoted string - no interpretation of the value of $var is performed at this point. 在后来引用$var双引号字符串中( "$var" )上面的文字变成双引号字符串的文本部分-没有价值的解释$var在这一点上进行。

What double-quoted strings expand to is treated as a single word (argument) by the shell (after removing the enclosing double quotes, a process called quote removal ). shell引用的双引号字符串被视为单个单词(参数)(在删除封闭的双引号后,称为引用删除的过程)。

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

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