bashshell

In shell, do variable expansions occur inside command substitution?


I know variable expansions happen before command substitution, but I am still not sure about this.

Given "name" is a shell variable with value "abc", when I run echo $(echo $name), which of the following is correct:

I tried the following.

$ name=abc
$ echo $(name=xyz; echo $name)

The code indeed outputs xyz, which suggests that the expansion of $name happens inside $(). That seems to contradict the rule that variable expansion happens because command substitution.

I do find a similar question order of expansion between variable expansion and command substitution, but it was 13 years ago, and that one does not have a convincing answer yet.


Solution

  • In the EXPANSION section of man bash:

           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.
    

    In the Command Substitution section:

           When using the $(command) form,  all  characters  between
           the parentheses make up the command; none are treated specially.
    

    So the command in $() is left untouched (there is no expansion in the command substitution), until it is executed in a sub-shell.
    Then, the same order of expansion is done (brace, tilde, param & var, arithmetic, command substitution, word splitting, pathname).

    We can therefore say with certainty that the result will be:

    $ name=abc
    $ echo $(name=xyz; echo $name)
    xyz