Web lists-archives.com

Re: Shell game? was Re: pmount could perhaps be of greater utility?




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