Andy Hu7,471 Points
Should it actually be "cp src/*.html build/ && cp src/*.css build/" because "&" in bash means run in background?
The tasks specified in package.json do run in shell right?
Alex KoumparosPython Web Development Techdegree Student 35,910 Points
Great question! We typically understand
& to mean 'run the specified command in the background', since this is our most common use case. However, the full behaviour of
& is a little more complicated than that, as we see when chaining multiple commands.
npm runs a script, it does it by calling
sh is a standardised definition of a shell that any POSIX-compatible Unix implementation is required to provide. In many (most) Unix distributions,
sh is not a shell itself, but a link to a
sh-compatible shell (often
Dash). Since any of these shells are
sh compatible, we can look at the
sh documentation to dig into how
In Shell, there are a couple of types of lists: 'AND-OR' lists and 'AND' lists.
AND-OR lists are defined as sequences of pipelines separated by
||. When executing a sequence of commands separated by
&&, shell will execute each next command if the previous command completed successfully (
|| separated commands execute if the previous command completed with an error code).
AND lists are defined as sequences of AND-OR lists (which could be a single command: a sequence of one) that are separated by
&. These lists execute unconditionally (i.e., without regard to whether the previous command exited successfully or not). The difference between
& is that the former will execute sequentially in the same shell (i.e., synchronously) but the latter will send each command to a subshell and so the commands can execute asynchronously.
It is this property of sending the command to a subshell for asynchronous execution that we exploit when we want to run a single command in the background.
In Andrew's example, the execution of the second copy operation does not require the first operation to have completed successfully (or at all), so to maximise performance we can execute the commands asynchronously using
& instead of
Hope that clears things up for you.