michael_J
michael_J

Reputation: 143

What is the difference between ( command1 command2 ) and ( command1; command2)?

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

Answers (1)

Amadan
Amadan

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

Related Questions