Part 1
echo one &&
echo two &
echo three &&
echo four
This can be rewritten as
echo one && echo two &
echo three && echo four
The reason you get the three
and four
first is simply that it takes longer to get the subshell handling the one
and two
up and running than it does to print the three
and four
.
You can see this a little more clearly like this
echo one && echo two &
sleep 1
echo three && echo four
In this situation you get one
and two
, followed a second later by three
and four
.
Note that in the original scenario there is no guarantee that the one
and two
won't be mixed in with the output of three
and four
, conceiveably even with words being interpolated, such as thonreee
or twfouro
.
Part 2
echo one &&
(echo two &)
echo three &&
echo four
This can be rewritten as
echo one && (echo two &)
echo three && echo four
Here what is happening is that the one
is printed immediately, and then the two
is fired off in a subshell. Then (serially) the next line is executed, resulting in three
and four
. In your particular situation the subshell is small and fast enough that the two
can be printed before the three
is output. No guarantee of this, though, either.
Part 3
The brackets group statements together into a subshell. The ampersand &
applies to a statement, but in this case you have used &&
to link the two commands together so they have to be treated as a single statement.
Perhaps you should be using echo one; echo two
rather than echo one && echo two
? They are very different. The semicolon ;
separates two commands, which then run independently but sequentially. The double ampersand &&
joins the two commands together as a logical AND, such that the second will only run if the first one completes successfully. Compare false; echo yes
, false && echo yes
, and true && echo yes
. Then experiment by replacing &&
(logical AND) with ||
(logical OR).
Bonus
You lose the job control notification because the subshell doesn't have job control.