Dynamics between parameter expansion and arithmetic expansion in echo $a$((a=2))$a

Shell is: GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

I’m considering the following command line:

a=1; echo $a$((a=2))$a

The output is:

122

I deduct that the expansion is processed in the following order:

  1. The variable a is assigned the value 1 ;
  2. The first $a is expanded via paramet expansion with a=1
  3. Then arithmetic expansion of $((a=2)) is performed, setting a to
    2,
  4. Then the second $a is expanded with new value of a that was set
    to 2 at arithmetic expansion.

If my understand is correct, that processing order means that the shell circles back to parameter expansion after having proceeded to arithmetic expansion.

And this contradicts my understanding of the GNU bash manual which states that there is clear order in bash expansion: arithmetic expansion being performed AFTER parameter expansion.

Is someone able to explain what’s at play here?

Asked By: yossi-matkal

||

this contradicts my understanding of the GNU bash manual which states that there is clear order in bash expansion: arithmetic expansion being performed AFTER parameter expansion.

That’s not what man bash states. Read carefully:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.

Note the use of commas and semicolons. Tilde, parameter, variable, and arithmetic expansions, and command substitution all happen at the same level, left to right, in accord with the observed behaviour.


FWIW, the POSIX text has clearer formatting in its corresponding section. It says:

The order of word expansion shall be as follows:

  1. Tilde expansion, parameter expansion, command substitution, and arithmetic expansion shall be performed, beginning to end. See item 5 in Token Recognition.

  2. Field splitting shall be performed on the portions of the fields generated by step 1, unless IFS is null.

  3. Pathname expansion shall be performed, unless set -f is in effect.

  4. Quote removal shall always be performed last.

Answered By: choroba
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.