Reputation: 481
Let's say we have a command output a variable assignment string, say 'var=foo', if I put this command in Command Substitution which looks like
$(echo var=foo)
, it causes 'command not found' error.
[223212 dot@anne ~]$ var=foo
[223226 dot@anne ~]$
[223230 dot@anne ~]$ $(var=foo)
[223235 dot@anne ~]$
[223236 dot@anne ~]$ $(echo var=foo)
bash: var=foo: command not found
[223240 dot@anne ~]$
[224909 dot@anne ~]$ $(echo ls)
a b c d
[225036 dot@anne ~]$
[225110 dot@anne ~]$ $(echo $(var=foo))
[225116 dot@anne ~]$
Since we can directly put variable assignment in Command Substitution like this $(var=foo)
(though it's meaningless I think), and $(echo ls)
works as expected as well, why output a assignment in Command Substitution causing error?
This is man bash
about Command Substitution:
Command substitution allows the output of a command to replace the command name.
Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
As I understand it, $(echo var=foo)
should be replace by var=foo
just like $(var=foo)
.
Am I getting it wrong?
Upvotes: 4
Views: 336
Reputation: 123470
Here's man bash
:
SIMPLE COMMAND EXPANSION
When a simple command is executed, the shell performs the fol‐
lowing expansions, assignments, and redirections, from left to
right.
1. The words that the parser has marked as variable
assignments (those preceding the command name) and
redirections are saved for later processing.
2. The words that are not variable assignments or redirec‐
tions are expanded. If any words remain after expan‐
sion, the first word is taken to be the name of the
command and the remaining words are the arguments.
[...]
In your case, the simple command has a single word $(echo var=foo)
.
Since there are no words marked as variable assignments (because this word is instead a command substitution), step 1 doesn't apply.
We then move on to step 2, where the word $(echo var=foo)
is expanded into var=foo
. We don't go back to the first step, we just do what step 2 says: "take the first word as the name of the command".
This is why var=foo
is executed as a command instead of being interpreted as an assignment.
Upvotes: 6