22

I have a bash script that I want to globally enable set -e.

But rather than disable it and reenable it all the time, I'm wondering if there is a way of selectively disabling error handling just sometimes. For example, commands run from systemd can be preceeded by a minus to ignore errors. Does bash has an equivalent?

e.g.

#!/bin/bash

set -e

WAN_IF=eth2

# Ignore error on next line
tc qdisc del dev ${WAN_IF} root

# I want errors to stop the script on this line
tc qdisc add dev ${WAN_IF} root handle 1: htb default 10

...
etc

Because of the need to enable/disable a lot I don't want to have to keep doing the following:

set +e
tc qdisc del dev ${WAN_IF} root

# I want errors to stop the script on this line
set -e
tc qdisc add dev ${WAN_IF} root handle 1: htb default 10
...
4
  • 1
    Instead of explicit set -e, I would recommend this: old_set=$-; set +e; <code_returning_exit!=0>; set -$old_set. Just in case set -e is not already set, you don't want to set it unnecessarily. functions are re-usable. So they may be called in a case when set -e is not set. This precaution may not be required in a script, but in interactive shells, it may be relevant. Commented Apr 20, 2015 at 3:58
  • Thanks @EtanReisner - would you like to put that into an answer so others can see it. It works perfectly. Commented Apr 20, 2015 at 4:09
  • 4
    The problem with set -e isn't that you have to be careful about which commands you want to allow to fail. The problem is that it doesn't compose. If someone else reads this post and uses source yourfile || : to source this script while allowing failure, suddenly yourfile will no longer stop on errors anywhere. Not even on failing lines after an explicit set -e. Commented Apr 20, 2015 at 4:17
  • This thread on superuser: How to disable set -e for an individual command? has better answers. Commented Feb 22, 2022 at 9:01

2 Answers 2

14

Add || : (or anything else that is guaranteed not to fail but that's the simplest) to the end of the command.

Though many people would simply tell you that set -e isn't worth it because it isn't as useful as you might think (and causes issues like this) and manual error checking is a better policy.

(I'm not in that camp yet though the more I run into issues like this the more I think I might get there one day.)

From thatotherguy's comment explaining one of major the issues with set -e:

The problem with set -e isn't that you have to be careful about which commands you want to allow to fail. The problem is that it doesn't compose. If someone else reads this post and uses source yourfile || : to source this script while allowing failure, suddenly yourfile will no longer stop on errors anywhere. Not even on failing lines after an explicit set -e.

Sign up to request clarification or add additional context in comments.

1 Comment

Seeing as no one will be using my script for anything other than its intended purpose I'm fine with the limitations. Thank you.
2

||: is ambiguous about what it's doing. Future code readers or future you might be confused. How about an explicit echo:

some_command_allowed_to_fail || (echo "this echo is just to \
    disable the error status" > /dev/null)

(Edit: add >/dev/null to avoid unnecessary showing the message to the user)

2 Comments

A comment about ||: removes the ambiguity. That's what they are for.
Why not just use || true then... Why add a whole new line for a comment @hookenz...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.