Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

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.

Quick Jump: Examples | Demo Video

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
  • Semicolon (;)
    • It’s used to sequence and terminate commands
      • 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
  • Both
    • The last run command in your sequence will be the returned exit code
      • ie., true && true && false and true ; true ; false will return exit code 1


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


  • 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.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.