[英]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. '
. '
开头。 "
- 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"
,双引号表示$var
被var
的值替换,但没有进一步的解释; 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. \\'
- 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. "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.