bug-bash
[Top][All Lists]
Advanced

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

Re: Incorrect alias expansion within command substitution


From: Chet Ramey
Subject: Re: Incorrect alias expansion within command substitution
Date: Sat, 5 Feb 2022 13:55:32 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.4.1

On 2/4/22 6:17 PM, Alex fxmbsw7 Ratchev wrote:
what about this viewing point
aliases can start, $(('s, but not end... this is unlogic

Well, I don't know about `unlogic' but there's an understanding deficit,
for sure.


alias -- \
p='printf %s\\n ' \
assign='assign=$(( ' begin='$(( ' \

for data in "1 + 2"
do
alias -- data="$d "
p begin data ))
done

this works and results 3

OK, let's go through it. I'll gloss over some non-essential details and
simplify others. I'll skip over the bulk of the for loop parsing and just
cover the simple command where alias expansion takes place.

Since `p' is in a command position, it gets alias expanded to
`printf %s\\n '. The lexical analysis restarts, the two words get scanned,
and we start a simple command. The expansion ends with a space, so the next
token (`begin') undergoes alias expansion, gets expanded to `$(( ', and the
lex restarts. We read `$((' and know we're reading the start of a word that
begins with an arithmetic expansion. We keep reading as if we are reading a
double-quoted string, looking for `))', since that's what you do while
reading an arithmetic expansion. There is no alias expansion because we are
not reading a new token and the contents of the arithmetic expansion are
treated like a double-quoted string, both disqualifying conditions. We find
those two characters, closing the arithmetic expansion, and go on looking
for the end of the word. We read a newline, which delimits the token, which
is the (shell grammar) WORD `$((  data ))'.

After we finish parsing the for loop, we go back to execute it. We run
a useless `alias' command, then come to the simple command

printf %s\\n $((data))

(I removed the spaces from the arithmetic expansion to make it clear that
it's one word.)

We begin to expand the words in this simple command. When we come to the
arithmetic expansion, we take the contents (`data') and run them through
the arithmetic evaluator. We get an identifier (`data'), assume it's a
shell variable, look up its value (`1 + 2', since that's how the for loop
set it) and evaluate that as an expression. It evaluates to 3, and the
string "3" becomes the result of the arithmetic expansion.

We run

printf %s\n 3

and get `3' as output.

Understand?

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/



reply via email to

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