[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: |
Sun, 26 May 2024 23:33:12 +0200 |
Hey Greg.
I'm afraid I still don't get the system behind it.
On Sun, May 26, 2024 at 10:27 PM Greg Wooledge <greg@wooledge.org> wrote:
> On the right hand side of # or ## you're allowed to have a glob. The
> glob may be contained in a variable, or written out explicitly.
>
> If any of the characters of the glob are quoted, they lose their special
> meaning. This also applies if the glob is in a variable, and the variable
> expansion is double-quoted. In that case, all the characters of the glob
> are considered quoted, and therefore non-special.
That was - I guess - already clear to me. For # ## % and %% it's like
there are two levels of quote removal, first on the word and then on
the whole ${...} (if surrounded by quotes).
Here the rules seem just normal as one would expect:
E.g. ${foo##$var},as you say if var is not DOUBLE(!) quoted, any
meta-characters in the value of var will keep their special meaing,
but if it's double quoted, they will be literal (but $var will still
be expanded).
OTOH, if only single quoted like in ${foo##'$var'}, there won't be
even a expansion.
Right?
As in:
$ bar='*'
$ foo='$barbaz'
$ printf '%s\n' ${foo##$bar}
$ printf '%s\n' ${foo##"$bar"}
$barbaz
$ printf '%s\n' ${foo##'$bar'}
baz
$
Also, the quotes are always removed.
For the above, the current POSIX
(https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02)
says:
" Enclosing the full parameter expansion string in double-quotes shall
not cause the following four varieties of pattern characters to be
quoted, whereas quoting characters within the braces shall have this
effect."
Which I guess describes the above behavior, in other words: there is a
2nd level of quoting for the word part, right?
What I still don't get are the :- :+ etc.:
For the the current POSIX says:
"word shall be subjected to tilde expansion, parameter expansion,
command substitution, and arithmetic expansion." so no quote removal,
but the most recent draft already corrected that as an error and says:
"word shall be subjected to tilde expansion, parameter expansion,
command substitution, arithmetic expansion, and quote removal."
> > x="${1:-$bar}" | bash x.sh "" | expanded
> > x="${1:-"$bar"}" | bash x.sh "" | expanded
>
> Because the right hand side of ## has special globby rules, the right hand
> side of - or :- gets treated the same way, to minimize surprises.
The "same way"? It does seem to get handled quite differently than for
##, # and friends?!
> Double quotes around $bar do not prevent the variable expansion, but they
> would suppress any glob behavior in the result. Since :- doesn't perform
> globbing anyway, you don't see a difference here.
Still fine with that, because if one has a normal string, "..." also
doesn't prevent expansions:
But above with ##, single quotes *did* prevent expansion. Why not here:
x="${1:-'$bar'}" | bash x.sh "" | 'expanded' => why not quote
removal, why expansion?
> > x="${1:-'$bar'}" | bash x.sh "" | 'expanded' => why not quote
> > removal, why expansion?
>
> Because it's what people expect. The $ being inside single quotes makes
> it a literal $ rather than the beginning of an expansion.
Yes but it *IS* expanded, if there are double quotes around it:
$ bar=expanded
$ printf '%s\n' "${unset:-'$bar'}"
'expanded'
And what's even more weird, above, there is no quote removal (of the
single quotes), but below there IS:
$ printf '%s\n' "${unset:-$'$bar'}"
expanded
zsh, makes that different:
% bar=expanded
% printf '%s\n' "${unset:-'$bar'}"
'expanded'
% printf '%s\n' "${unset:-$'$bar'}"
$'expanded'
which seems at least more consistent.
OTOH, zsh handles this a bit unexpected:
% printf '%s\n' ${some_unset_var:-foo bar}
foo bar
(i.e. it makes one word out of foo bar and not two, as bash does:
$ printf '%s\n' ${some_unset_var:-foo bar}
foo
bar
If I have:
"${unset:-"$bar"}"
How is that processed? Is it an inner word "$bar"
and an outer "${unset:-<result from word>}"
or is it like three strings: "${unset:-" $bar "}"
?
Thanks
Philippe.
- How does quote removal work with alternative forms of parameter expansion?, Philippe Cerfon, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Philippe Cerfon, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Greg Wooledge, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?,
Philippe Cerfon <=
- Re: How does quote removal work with alternative forms of parameter expansion?, Greg Wooledge, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Philippe Cerfon, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Greg Wooledge, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Lawrence Velázquez, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Philippe Cerfon, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Lawrence Velázquez, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Philippe Cerfon, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Lawrence Velázquez, 2024/05/26
- Re: How does quote removal work with alternative forms of parameter expansion?, Chet Ramey, 2024/05/29
Re: How does quote removal work with alternative forms of parameter expansion?, Koichi Murase, 2024/05/26