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@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@Q} > bash: ${#ABC@Q}: bad substitution The #variable is the entire expansion, not the `parameter' part of an expansion. > $ echo ${PWD:1:3@Q} > bash: PWD: 3@Q: value too great for base (error token is "3@Q") > $ echo ${PWD:1@Q} > bash: PWD: 1@Q: value too great for base (error token is "1@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@walrus} > > $ echo ${!P@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@walrus} > > $ echo ${!ABC@} > ABC > $ echo ${!ABC@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 c...@case.edu http://tiswww.cwru.edu/~chet/ _______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net