Reputation: 143
What is the difference between ( command1 command2 )
and ( command1; command2)
?
Anyone could give some detail explanation for this. Here is my test result:
( a=3; echo $a) #the result is 3
but
( a=3 echo $a) #the result shows nothing
Upvotes: 1
Views: 311
Reputation: 198476
a=3; echo $a
is two commands. a=3 echo $a
is one command (it is obvious that it cannot be two commands since you can't say echo foo echo bar
and expect the two commands to evaluate correctly), which evaluates a command in an environment where a=3
. Bash manual defines this syntax under "Simple commands":
A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator.
The important bit is the order: the variable substitution is the first thing that occurs; then prefixed assignment will change the sub-environment; then the command is evaluated.
In detail: the first one, a=3; echo $a
will
1) evaluate a=3
and insert binding a=3
in current environment
2) evaluate echo $a
by substituting the current environment variables, obtain echo 3
, then output 3
.
The second one is a bit more complex. a=3 echo $a
, being a single command, will
1) evaluate a=3 echo $a
by substituting the current environment variables. Since a
is not defined, we obtain a=3 echo ""
. It then makes a new environment where a=3
, and evaluates echo ""
there.
It is easier to see if we switch the command to be a=3 bash -c 'echo $a'
. Since $a
is single-quoted, it will not be evaluated, so the command will run bash -c 'echo $a'
in the environment where a=3
. bash
will then evaluate its command, echo $a
, in its environment, which will now include a=3
, obtain echo 3
, and print 3.
It is interesting to contrast it with a=3 bash -c "echo $a"
. Since $a
is double-quoted, it will be evaluated; the command becomes bash -c 'echo ""'
, which is then evaluated in a sub-environment where a=3
, printing an empty line.
Another difference is that a=3 echo $a
runs echo
in a sub-environment where a=3
, but after that line a
is back to being undefined (or having whatever value it had before). In a=3; echo $a
, the current environment is permanently changed, and $a
will be 3
until changed again.
Upvotes: 3