bug-bash
[Top][All Lists]
Advanced

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

Re: bash tries to parse comsub in quoted PE pattern


From: Martin D Kealey
Subject: Re: bash tries to parse comsub in quoted PE pattern
Date: Sun, 22 Oct 2023 19:47:59 +1000

On Wed, 18 Oct 2023 at 22:19, Zachary Santer <zsanter@gmail.com> wrote:

> On Tue, Oct 17, 2023 at 5:56 PM Emanuele Torre <torreemanuele6@gmail.com>
> wrote:
>
> >     bash-5.1$ letters=( {a..z} ); echo "${letters["{10..15}"]}"
> >     k l m n o p
>
...

> So how important is it to maintain undocumented behavior?
>

This is the expected outcome of doing brace expansion *followed by*
variable expansion, with separate parsing phases. Bash does not generally
document what happens when you combine features if it can reasonably be
inferred from the documentation of the individual features.

First, brace expansion translates:
"${foo["{10..15}"]}"
into
"${foo["10"]}" "${foo["11"]}" "${foo["12"]}" "${foo["13"]}" "${foo["14"]}"
"${foo["15"]}"
and then the variables are expanded individually.

Then there's the question "Was that even supposed to work like that?"


Supposed to? Yes. A good idea? Probably not. Useful? Definitely, but there
should be a better way to do it.

If so, you'd think it would generalize to being able to pass a series of
> whitespace-delimited indices to an array expansion.
>

That does not follow. The shell grammar is characterised by having a large
number of phases, which means brace expansion occurs without regard for the
grammatical validity of "${var[" as its prefix or "]}" as its suffix; when
the brace expansion occurs, the prefix and suffix are not yet considered as
being a variable expansion.

Putting an array or list inside the [] won't be expanded until after the
outer variable expansion has begun, so it would require entirely new rules
for handling array subscripts that are "lists". And that *would* need to be
separately documented.

Of course, I would love to see something like "${array[10..15]}" work
"properly", unlike the current behaviour of "${array[@]:10:6}"

(The latter unnecessarily exposes the user to the implementation details of
"array". Whenever I complain about this, the responses justifying the
current behaviour as "sensible" tacitly rely on "it's a list, not an
array", which is quite perverse given that all the documentation is about
"arrays".)

Why does "${#@}" expand to the same thing as "${#}"?


You're right, we don't need ${#} and we should get rid of it. </jest>

${#@} follows the pattern of correspondence between ${array[@]} and ${@};
they both take all the same modifiers, including the # prefix for "count".

Ignoring which one came first, $# can be seen simply as a required
shorthand for ${#@}.


> Why is $[  ]  equivalent to $((  ))?


Because POSIX was too slow choosing which one to endorse (there were
several proposals), by which time Bash had already implemented $[...], and
people had started using it. (And from a language design choice, $[...] is
simpler to get right; no need to look ahead for '))' to see if it's
actually a command substitution.)

Does that stuff need to continue to work forever?
>

For some combination of default modes, yes, it must. There are still
scripts out there running that haven't been modified this millennium.

That's not to say that there shouldn't be a "lint" mode which warns about
obsolete features, or a "strict" mode which aborts if they're used, but
they can't just be removed from the default.

-Martin


reply via email to

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