2022年11月4日(金) 8:48 Greg Wooledge <g...@wooledge.org>: > On Thu, Nov 03, 2022 at 05:20:52PM -0400, Greg Wooledge wrote: > > On Fri, Nov 04, 2022 at 04:09:10AM +0900, Koichi Murase wrote: > > > When one wants to also support Bash 4.2, one possible workaround is to > > > assign the result to a variable (without quoting the right-hand side > > > of the assignment): > > > > > > $ bash-4.2 -c 'string=\"hi\"; string=${string//\"/\"}; echo > > > "$string"' > > > $ bash-4.2 -c 'str="a string"; rep="a&b"; str=${str//a/"$rep"}; echo > > > "$str"' > > > > > > These work as expected in all Bash versions I can test (2.0..5.2). > > > > That's amazingly clever. You're forcing the semantics of double-quoting > > the right-hand side (implicitly, due to the simple assignment), without > > putting actual quotes in it. > > Hmm, no, you *are* including quotes, so that's not why it works. > I actually have no idea why it works.
Ah, sorry for confusing you. By "without quoting the right-hand side", I meant that we strip the *outer* quoting of the entire right-hand side. More explicitly, string="${string//\"/\"}" still does not work in Bash 4.2 or with `shopt -s compat42', but string=${string//\"/\"} works. I think you already know it, but this is because, in Bash 4.2, quoting inside the parameter expansion (i.e., \& in this case) is affected by the context of the parameter expansion itself (i.e., ${string ...}). When ${string ...} is placed inside the outer double quotes "${string ...}", the inner quoting is also treated as if it is inside the double quotes, i.e. \& is treated as literal \&. When ${string ...} is not placed inside the double quotes, the inner quoting is processed as if it is directly in the right-hand sides of assignments, so \& becomes &.