Difference between parsing order and expansion order

Viewed 37

I noticed that books and online manuals report two different orders for the recognition and the execution of expansions.

https://www.gnu.org/software/bash/manual/bash.html#Shell-Expansions

[diagram from a book][1] [1]: https://i.stack.imgur.com/b79Hw.jpg

Considering the following:

$(((5+2)))
7: command not found
  1. I think that the shell first recognizes the command substitution and then the arithmetic substitution.
  2. shell executes first the arithmetic substitution and then the command substitution

Is the order of parsing different from the order of execution or is the order on the image wrong? Why $((((5+2)))) gives 7: command not found just like $(((5+2))) ?

1 Answers

The bash reference manual states (emphasis mine):

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 filename expansion.

So, yes, the book diagram is wrong, but that's not the point. There is no command substitution happening in your example:

  1. $((...)) means: arithmetic expansion.

  2. ... is either (5+2) (first example) or ((5+2)) (second example). Both evaluate to 7.

  3. Thus, the whole expression evaluates to 7.

    me@myPC:~$ echo $(((5+2)))
    7
    me@myPC:~$ echo $((((5+2))))
    7
    

Obviously, if you just type $(((5+2))) in a command line, bash (a) evaluates it to 7 and then (b) tries to run a command with that name, and fails:

me@myPC:~$ 7
7: command not found
me@myPC:~$ $(((5+2)))     # same thing
7: command not found
Related