I'm confused in the way bash parses input and performs expansion.
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.
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. 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.
I'm coming from shell-operation, and shell expansion.
All of the interesting things happen in the assignment, 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. 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"
. 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.
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:
''
- 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.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"'
...and many others. bash could technically have printed any of these under set -vx
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With