help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How does quote removal work with alternative forms of parameter expa


From: Philippe Cerfon
Subject: Re: How does quote removal work with alternative forms of parameter expansion?
Date: Mon, 27 May 2024 02:38:44 +0200

Hey Koichi.

On Mon, May 27, 2024 at 1:57 AM Koichi Murase <myoga.murase@gmail.com> wrote:
> those in the
> string in ${var:-str} are processed as if the string is inside the
> double quotations when the whole parameter expansion is inside the
> double quotations.

I see. That's why I had asked in some mail before if
"${var-"$foo"}" is actually more like "${var-"    $foo    "}"

Just out of curiosity:
Is there any place in the POSIX text from where I could have deduced
that behavior? Cause from the places I've read there I'd have rather
interpreted that *both* types of parameter expansion forms do that 2
(independent) levels of expansion/quote removal.
Even more so, with the changes they've made in the draft.
Or is that all just bash/dash behavior?


> > So it seems as if there'd be first a "normal" quote removal on the
> > word part of these parameter expansion forms and then the outer quote
> > removal, right?
>
> Yes.

And we're still taking about only the # ## % and %% forms here, right?


> > But now, using one of the :- :+ etc forms:
> >      x            |   invocation    |   output
> > [...]
> > x="${1:-"$bar"}"  |  bash x.sh ""   |   expanded
>
> It becomes equivalent to something like x=""$bar"", and the value
> becomes the expansion result of $bar. An interesting behavior is that
> the «"» inside the double quotations toggles the expansion behavior
> (as if the first " inside double quotes is paired with the opening
> double quotation, and the second " inside double quotes is paired with
> the closing double quotation):

Why does:
$ bar='1 2'
$ printf '%s\n' "${unset_var:-"$bar"}"

then result in:
1 2
and not:
1
2

?
If the above would be like ""$bar"" I'd have thought the $bar is not
quoted and thus produces separate fiels?

And again, is the above


e.g. you can check the behavior of
>
>   x="${1:-"foo\ bar"foo\ bar"foo\ bar"}"
>
> which becomes
>
>   foo barfoo\ barfoo bar
>
> This is because it is somewhat equivalent to
>
>   x=""foo\ bar"foo\ bar"foo\ bar""
>
> This behavior seems strange, but this is the traditional behavior of
> Bash. As far as I can test, Bash 2.0 of 1996 (28 years ago) already
> has this behavior. ksh93 seems to behave in the same way.

Is this coupling then also POSIX behaviour?
Cause if I do the same with e.g. dash I get:
$ printf '%s\n' "${unset:-"foo\ bar"foo\ bar"foo\ bar"}"
foo\ barfoo\ barfoo\ bar

Because of this <see below>



> > x="${1:-'$bar'}"  |  bash x.sh ""   |   'expanded'  => why not quote
> > removal, why expansion?
>
> It becomes equivalent to: x="'$bar'", where single quotations are
> placed inside "" so are left in the final value.
>
> > x="${1:-$'$bar'}" |  bash x.sh ""   |   expanded    => why expansion?
>
> This is a separate feature `shopt -s extquote', which is turned on by
> default. If you want to focus on the Bash behavior of quoting and
> expansions, you should turn off it by `shopt -u extquote'.

and because of that:
Is there even a way, when using the + - = ? forms, to use quoting in
the word part and still be portable?
It would seem to me that backslash quoting is then the only portable way?


> Another case you might be interested in is
>
> x="${1:-"foo \bar"foo\ bar"foo\ bar"}"

What especially do you mean here? It's like the above case, just that
this time the there's a backslash escaped b (outside of double quotes
or dollar single quotes)?
So at least in bash it should be like:
""foo \bar"foo\ bar"foo\ bar""

> > $ printf '%s\n' "${some_unset_var:-'foo bar'}"
> > 'foo bar'
> > => why not quote removal?
>
> It becomes "'foo bar'".
>
> > $ printf '%s\n' "${some_unset_var:-foo\ bar}"
> > foo\ bar
> > => why not quote removal?
>
> This becomes equivalent to "foo\ bar", and the backslash inside the
> double quotations are only processed when it is paired with $, ", `,
> or \.
>
> > $ printf '%s\n' ${some_unset_var:-foo\ bar}
> > foo bar
> > => contrary to the above, always with quote removal
>
> This becomes equivalent to «foo\ bar», where «\ » is outside the
> double quotation and thus is processed.

I guess I do (kind of) understand now how it's done in bash, but which
rules should one follow if one tries to program portably?

No single/dollar-single/double quoting at all within the word part of
- + = ? parameter expansions (at least not, when the parameter
expansion is itself within double quotes?

Thanks,
Philippe.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]