Difference between Double Ampersand and Semicolon in a Shell Script
Sometimes they appear to do the same thing but there is quite a big difference between both solutions.
Prefer video? Here it is on YouTube.
You typically use these when chaining commands together, here’s the short version:
- Double ampersand (
&&
)- It’s a logical
AND
- Supports short circuiting
- ie., if the first condition fails then it will exit before evaluating the rest
- It’s a logical
- Semicolon (
;
)- It’s used to sequence and terminate commands
- New line characters are interchangeable with using
;
- New line characters are interchangeable with using
- Runs every command in serial regardless if the previous command fails
- If your script has
set -o errexit
then the first failing command will halt- That’s because that option will exit a script early if any command fails
- If your script has
- It’s used to sequence and terminate commands
- Both
- The last run command in your sequence will be the returned exit code
- ie.,
true && true && false
andtrue ; true ; false
will return exit code 1
- ie.,
- The last run command in your sequence will be the returned exit code
# Examples
For context, false
is a command that exits 1 with no output and true
is a
command that exits 0 with no output. Both commands are built into your shell
such as bash or zsh.
# In this case `set -e` or `set -o errexit` is not set.
$ false && echo "OK"
# [exit 1] with no output.
$ false ; echo "OK"
# [exit 0] with OK.
$ true && echo "OK"
# [exit 0] with OK.
$ true ; echo "OK"
# [exit 0] with OK.
As for set -e
behavior, this is the only case that would change:
$ (set -e && false ; echo "OK")
# [exit 1] with no output.
We’re wrapping the commands in a command group (...)
so it runs in a
subshell. If we didn’t do this then your current terminal session would exit
which in turn means your terminal window would likely close due to the failing
false
command.
Real World Use Cases?
Like most things, “it depends” but…
sudo apt-get update && sudo apt-get upgrade
is a pretty good case for using
&&
because you wouldn’t likely want to upgrade your packages unless your list
of packages were updated first.
That’s not to say you can’t use sudo apt-get update ; sudo apt-get upgrade
.
If you did then the upgrade command will run even if the update failed. In a
practical sense that’s probably not what you want in most cases though.
To be honest, I almost always use &&
unless I know I want everything to run.
In my shell scripts I do set -o errexit
too. You can always opt-out of that
behavior for the small bits of your script where you expect errors and catch
them in a custom way.
With that said… ;
could be useful when you have independent tasks to run.
For example install_myapp ; install_anotherapp
. If both apps aren’t associated
with each other then a failure to install myapp shouldn’t block anotherapp.
Although in that case, if they are truly independent you might as well run them
in parallel as background tasks. For example, install_myapp & install_anotherapp &
. Notice the (1) &
there instead of (2) &&
. I’ve
written about background tasks in the past.
This is in no way shape or form meant to be an exhaustive list of use cases. I wanted to supply one of each so you have a brief awareness of how to use each one.
# Demo Video
Timestamps
- 0:34 – A few high level differences
- 3:15 – A quick primer on the true and false commands
- 4:11 – Running a few examples to see the differences
- 6:02 – How set -e changes things and a side topic on subshells
- 7:58 – A few use cases on when to use either options
How often do you use semicolons instead of double amps? Let me know below.