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: Koichi Murase
Subject: Re: How does quote removal work with alternative forms of parameter expansion?
Date: Mon, 27 May 2024 08:57:20 +0900

2024年5月27日(月) 1:19 Philippe Cerfon <philcerf@gmail.com>:
> I'm a bit lost to understand how quoting works with the word in
> alternative forms of parameter expansion.

The quote removal and expansions in the patterns of ${var#pat}, etc.
are processed as if it is an independent word, while 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.

> 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.

> 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): 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.

> 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'.

Another case you might be interested in is

x="${1:-"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.

--
Koichi



reply via email to

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