General Discussion

Andy Hu
Andy Hu
6,014 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?

1 Answer

Alex Koumparos
MOD
Alex Koumparos
Python Web Development Treehouse Moderator 31,925 Points

Hi Andy,

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.

When npm runs a script, it does it by calling sh. 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 Bash or Dash). Since any of these shells are sh compatible, we can look at the sh documentation to dig into how && and & behave.

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 && or ||. 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 ; or &. These lists execute unconditionally (i.e., without regard to whether the previous command exited successfully or not). The difference between ; and & 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 asychronously.

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.

Cheers

Alex

Andy Hu
Andy Hu
6,014 Points

So & and ; are basically at the same level, only & puts the former list into background and ; waits for the former one to complete.
I knew of ; is to seperate lists but didn't know that & is just another counterpart of it! Now I'm clear , thank you so much for your help!

Andy