On Tue 07 May 2019 at 10:12:10 (+1000), David wrote:
On Mon, 6 May 2019 at 23:53, Erik Christiansen wrote:
> On 06.05.19 09:03, Greg Wooledge wrote:
> > On Sat, May 04, 2019 at 01:48:01PM +0200, Jonas Smedegaard wrote:
[snipped all]
Hi Erik
Maybe you would enjoy answering this question then?
https://lists.gnu.org/archive/html/help-bash/2019-05/msg00000.html
Because apparently no-one else has, hehe :D
Hi everyone, I'm the poster of the above query and I have just
subscribed here. Replying via the web link so if there is any
discussion, list thread won't break (hopefully).
My take on this problem goes as follows.
B is easy. man bash says "When the old-style backquote form of
substitution is used, backslash retains its literal meaning except
when followed by $, `, or \." So the \\ in B's inner echo becomes
\ in the outer echo. BB shows the result of running the outer echo
on the substitution made in B.
A is tricky, mainly because of the middle Quotation Mark¹. So the first
thing I would do is substitute a benign character, like x. The result
of that substitution is shown at J. Work with that, and then change x
back to Quotation Mark at the end.
So K runs the inner echo and shows the result. L then runs the outer
echo on that result (leaving out the [] brackets). Because \x is
meaningless in double quotes, it survives the outer echo untouched.
Running the result of a command execution and allowing the result
to control delimiters, dropping out of the string? Now that gives
me the jeebies, security-wise. :-)
If you try to encapsulate the \" in a separate script file, then
it appears the above does not occur. Try this:
test.sh:
#/bin/bash
echo \"
$ echo "`./test.sh \\"`"
"
The " returned by test.sh doesn't close anything. \\" is passed as
argument to test.sh (I guess as \") and disappears. Unless echo as
a built-in (is it?) behaves differently. Still, the power to
control the parent's delimiters seems unlikely, IMHO.
I have since been studying the bash sources, and posted another
query yesterday, see:
http://lists.gnu.org/archive/html/help-bash/2019-05/msg00006.html
To summarize, consider our usual examples:
echo "[` echo \" \\" \" `]" A # [ " ] A
echo "[` echo \" \\x \" `]" J # [ \x ] J
Here's a theory: Inside the inner backquotes, \" gets escaped into
" because token processing sees the current delimiter as ". (But
matched pair processing sees the inner delimiters as ``.) The \\"
becomes \" and the \\x becomes \x. The inner commands are then run as:
echo " \" "
echo " \x "
giving the expected result. When entering the matched pair
processing function for the inner ``, the delimiter stack was not
updated, so the token function still sees the current delimiter as
the outer one, which is ".
This is based on what I have studied in the sources, and it
doesn't make any sense to me from a syntax point-of-view, so I
hope I can eventually get a useful and definitive answer from the
bash maintainers.
Now put back the Quotation Mark in place of x. man bash says "A double
quote may be quoted within double quotes by preceding it with a
backslash." And that's what we've got in M.
Now working outwards, I've added the [] brackets at LL and MM, where
they play no role. Finally the outer double quotes: because they pair
up with the double quotes from L, that leaves the \x exposed to the
outer echo and it becomes just x.
Who processed the \" into " in A? The outer echo (or, if you like, the
shell handing the arguments to the outer echo).
Over to Greg for checking.
¹ Quotation Mark rather than double quote because it never plays the
role of an active double quote as far as bash is concerned.
--
Cheers,
Kein-Hong Man (esq.)
Selangor, Malaysia