Bash解析和Shell扩展 [英] Bash parsing and shell expansion
问题描述
我对bash解析输入并执行扩展的方式感到困惑.
I'm confused in the way bash parses input and performs expansion.
对于输入来说, \'"\" hello world \"
作为bash中的参数传递给显示其输入内容的脚本,我不确定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.
示例
var=\'"\"hello world\""
./displaywhatiget.sh "$var"
I got '"hello world"
我知道"$ var"
中的双引号告诉bash一起对待 var
的值.但是,我不了解的是何时在bash的扩展过程中进行反斜杠转义和对值进行双引号解析.
I understand that the double quotes in "$var"
tells bash to treat the value of var
together. 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.
推荐答案
所有有趣的事情都发生在赋值 var = \'"\" hello world \"
中.让我们分解一下:
All of the interesting things happen in the assignment, var=\'"\"hello world\""
. Let's break it down:
-
\'
-这是一个转义的单引号.如果没有转义符,它将以单引号开头的字符串开始,但是转义符只是字面意义上的单引号.因此,最终的字符串将以'
开头. -
"
-这将开始一个双引号字符串. -
\"
-一个转义的双引号;与转义的单引号一样,它被视为文字双引号,因此"
将是第二个字符最后一个字符串. -
hello world
-由于我们仍在双引号字符串中,因此它会按字面意义包含在最终字符串中.请注意,如果此时我们不在双引号中,则空格将标记出字符串的结尾. -
\"
-另一个转义的双引号;再次包含在字面上,因此最终字符串的最后一个字符将是"
. -
"
-关闭双引号的字符串.
\'
- 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. 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.
因此, var
被分配了值'"hello world"
.在 ./displaywhatiget.sh"$ var"
中,双引号表示将 $ var
替换为 var
的值,但不会进一步解释;就是直接传递给脚本了.
Thus, var
gets assigned the value '"hello world"
. In ./displaywhatiget.sh "$var"
, the double-quotes mean that $var
gets replaced by var
's value, but no further interpretation is done; that's just passed directly to the script.
更新:使用 set -vx
时,bash以某种奇怪的方式打印任务.就像我在评论中说的,它的工作就是获取原始命令,将其解析(如上所述)以找出其含义,然后将其反向翻译以得到等效命令(即具有相同命令的命令)影响).它附带的等效命令是 var =''\''"hello world"'
.解析方法如下:
UPDATE: When using set -vx
, bash prints the assignment in a somewhat strange way. 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 (i.e. one that'd have the same effect). The equivalent command it comes up with is var=''\''"hello world"'
. Here's how that would be parsed:
-
''
-这是一个零长度的单引号字符串;它没有任何作用.我不确定为什么bash会包含它.我很想将其称为错误,但这并不是错误,只是完全没有意义.顺便说一句,如果您想删除引号的示例,请执行以下操作:在此命令中,这些引号将被删除而没有任何痕迹. -
\'
-这是一个转义的单引号,就像在原始命令中一样.最终的字符串将以'
开头. -
'
-这将开始一个单引号字符串.除了查找闭引号外,单引号内根本不执行任何解释. -
"hello world"
-由于我们位于单引号字符串中,因此它会按字面意义包含在最终字符串中,包括包含双引号和空格 -
'
-关闭单引号的字符串.
''
- this is a zero-length single-quoted string; it has no effect whatsoever. I'm not sure why bash includes it. I'm tempted to call it a bug, but it's not actually wrong, just completely pointless. 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."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.'
- this closes the single-quoted string.
因此它获得分配给 var
的相同值,只是编写方式不同.这些中的任何一个也将具有相同的效果:
so it gets the same value assigned to var
, just written differently. Any of these would also have the same effect:
var=\''"hello world"'
var="'\"hello world\""
var=\'\"hello\ world\"
var="'"'"hello world"'
var=$'\'"hello world"'
...还有许多其他.从技术上讲,bash可以在 set -vx
下打印任何.
...and many others. bash could technically have printed any of these under set -vx
.
这篇关于Bash解析和Shell扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!