If you use Bash's unofficial strict mode, you should use the new ShellCheck checks I added

What are the checks and how do I enable these bad boys?

Checks: SC2310, SC2311, SC2312.

They need to be enabled because they're optional. You can add these comments to you shell scripts, but I mention a couple other ways later on in this article:

# shellcheck enable=check-set-e-suppressed
# shellcheck enable=check-extra-masked-returns

What's Bash's unofficial strict mode?

Here's an article which describes it better than I can. The tl;dr is "set -euf -o pipefail". The idea is that it'll make your scripts safer by causing them to exit when something goes wrong. Well, that's the almost unanimous consensus on the internet and among even the smartest colleagues I've worked with. But I don't buy it.

What makes Bash's strict mode so dangerous that it needs its own ShellCheck checks?

This'll explain the perils, with plenty of examples too. The tl;dr is that it makes Bash's unintuitive behaviour even more unintuitive. You can empirically prove this by running some of the new checks, SC2310 and SC2311 on some Bash written by wicked-smaht engineers (like those at the place where I work, Canva). I did, and found a little over 300 errors.

What do the new ShellCheck checks do?

ShellCheck's author, Vidar Holen, explains the new checks here, on each of their Wiki pages:

  1. SC2310 – "This function is invoked in an 'if' condition so set -e will be disabled. Invoke separately if failures should cause the script to exit." (Note that this check also looks for other contexts where set -e is disabled, like in && lists and command substitutions.)
  2. SC2311 – "Bash implicitly disabled set -e for this function invocation because it's inside a command substitution. Add set -e; before it or enable inherit_errexit."
  3. SC2312 – "Consider invoking this command separately to avoid masking its return value (or use '|| true' to ignore)." (set -e won't cause commands whose return values are masked to exit the script.)

How can I start using them?

The first thing to do is compile ShellCheck from source. Because the checks were added so recently, they're not part of a release yet.

The second thing to do is enable the checks, because they're optional. One way to do it is to add these comments to your Bash code, as previously mentioned:

# shellcheck enable=check-set-e-suppressed
# shellcheck enable=check-extra-masked-returns

You could also use a .shellcheckrc file or CLI options. But right now, the nice thing about the comments is you can use them with ShellCheck's online demo, which runs the latest code on master, not just the latest release.

If you think set -e is so dangerous why don't you just stop using it? Why write a whole new set of ShellCheck checks?! It doesn't make any sense!

Everyone loves set -e but me lol, so I'm forced to use it at work. I can't see any technical reason for its use. I think it's all a social thing—A meme. Don't underestimate the power of memes.

Part if it is probably that people hate Bash so much that they don't want to think too hard about it, so they'll just copy the smartest guy in the office or the most upvoted comment on Stack Overflow. Fair enough.

Also, I agree that the principle that code should fail fast is a good one. So that argument is superficially convincing; You really can get code to fail fast with set -e. But few people stop to ask, "at what cost?" This is probably because Bash isn't sexy enough for people to learn it well enough to realise there's a problem with set -e in the first place.

Another thing is that I'm a nerd with no social capital and set -e gets memed harder than mechanical keyboards, so I have no option but to solve a social problem with a technical solution. Hopefully the new, constant warnings will show my otherwise reasonable colleagues the error of their ways. If not, I can always run off to Tibet and become a monk or something.

Other random stuff that didn't fit well into the rest of the article

I'm actually okay with the other "strict bash" options, like set -u and, to a lesser extent, set -o pipefail.

Also, remarkably, despite ShellCheck being pretty widely used in my experience, the new checks put me into the top 5% of contributors, measured by lines of code added. It's probably because nobody knows or uses Haskell except for hobby projects lol.