[Toybox] bash continues to confuse me.
Chet Ramey
chet.ramey at case.edu
Thu Jun 18 11:46:20 PDT 2020
On 6/17/20 1:22 PM, Rob Landley wrote:
> Trying to figure out when spaces are and aren't allowed in ${blah} led to asking
> why echo ${!a* } is an error but ${!a@ } isn't (when there are no variables
> starting with a), and I eventually worked out that:
>
> $ X=PWD
> $ echo ${!X at Q}
> '/home/landley/toybox/clean'
>
> Is going on?
It's variable transformation. It's introduced by `@' and uses single-letter
operators. I cribbed the idea from mksh and extended it. The syntax is kind
of loose because I'm still experimenting with it.
Which is just weird, both because:
>
> $ echo ${PATH@ }
> bash: ${PATH@ }: bad substitution
>
> And because:
>
> $ ABC=defghi; echo ${#ABC at Q}
> bash: ${#ABC at Q}: bad substitution
The #variable is the entire expansion, not the `parameter' part of an
expansion.
> $ echo ${PWD:1:3 at Q}
> bash: PWD: 3 at Q: value too great for base (error token is "3 at Q")
> $ echo ${PWD:1 at Q}
> bash: PWD: 1 at Q: value too great for base (error token is "1 at Q")
What's wrong with that? `@' and `Q' are valid characters in numeric
constants when the base is large enough to need them. You can use
bases up to 64 in base#constant.
>
> Hmmm...
>
> $ echo ${!potato at walrus}
>
> $ echo ${!P at walrus}
Invalid transformations just expand to nothing rather than being errors.
That's part of what I'm still experimenting with.
> $ echo ${!P@}
> PATH PIPESTATUS PPID PS1 PS2 PS4 PWD
Yep, variable transformation isn't in effect when the expansion ends with
the `@'.
>
> $ X=PATH
> $ echo ${!X@ }
> bash: ${!X@ }: bad substitution
>
> $ ABC=123
> $ echo ${!A at walrus}
>
> $ echo ${!ABC@}
> ABC
> $ echo ${!ABC at walrus}
>
> $ echo ${!A@ }
>
> Ok, when X exists and points to another variable, then !X becomes the contents
> of that other variable and THEN the @ cares about trailing garbage. But * is a
> different codepath from @...?
It's a different expansion.
>
> And when the ${!var} doesn't have contents pointing to another existing
> variable, it falls back to a codepath that tries the prefix stuff (and/or the
> array stuff, in some order?) and that codepath tries to parse trailing @Q and
> friends, but DOESN'T error out if it can't recognize the trailing stuff after the @?
Not really, no. It grabs the parameter, which may begin with `!', looks at
the character following it, does one character of lookahead if that
character is `@', and branches to the appropriate thing: variable prefix
expansion or indirect expansion with the result being used as the parameter
for the rest of the expansion.
>
> I'm pretty sure the array mangling logic ties in here somehow, but there's some
> missing error checking somewhere...
Invalid transformation operators just expand to nothing.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU chet at case.edu http://tiswww.cwru.edu/~chet/
More information about the Toybox
mailing list