The set -e command makes a bash script fail immediately when any command returns an non-zero exit code.

  1. Is there an easy and elegant way to disable this behaviour for an individual command within a script?

  2. At which places is this functionality documented in the Bash Reference Manual (http://www.gnu.org/software/bash/manual/bashref.html)?

7 Answers 7

  1. Something like this:

    #!/usr/bin/env bash
    set -e
    echo hi
    # disable exitting on error temporarily
    set +e
    echo next line
    # bring it back
    set -e
    echo next line


    $ ./test.sh
    ./test.sh: line 7: aoeuidhtn: command not found
    next line
    ./test.sh: line 11: ao: command not found
  2. It's described in set builtin help:

    $ type set
    set is a shell builtin
    $ help set
    Using + rather than - causes these flags to be turned off.

The same is documented here: https://www.gnu.org/software/bash/manual/bashref.html#The-Set-Builtin.

  • Thanks! I found another possibility: #!/bin/bash set -e # Uncomment next line to see set -e effect: #blubb if blubb; then echo "Command blubb was succesful." else echo "Command blubb failed. Exit code: $?" fi echo normal script exit
    – Gustave
    Jul 14, 2015 at 16:20

An alternative to unsetting the bail on error would be to force a success no matter what. You can do something like this:

cmd_to_run || true

That will return 0 (true), so the set -e shouldn't be triggered

  • 4
    faulty_cmd || : is another popular idiom for this. (The : is a command synonymous to true).
    – ulidtko
    Aug 26, 2016 at 12:24
  • 5
    @ulidtko - interesting. Led me down the rabbit hole to find this stackoverflow.com/questions/3224878/… to get the history on true vs. :
    – ernie
    Aug 26, 2016 at 17:55

If you are trying to catch the return/error code (function or fork), this works:

function xyz {
    return 2

xyz && RC=$? || RC=$?
  • 1
    Oh this one is clever. Couldn't find a way to use set -e and still grab the rc. Closest I came was putting the cmd in an if statement... which i guess this is. Much shorter though! Thanks! Aug 12, 2020 at 21:32

If the the "exit immediately shell option" applies or is ignored depends on the context of the executed command (see Bash Reference Manual section on the Set Builtin - thanks to Arkadiusz Drabczyk).

Especially, the option is ignored if a command is part of the test in an if statement. Therefore it is possible to execute a command and check for its success or failure within an "exit immediately context" using an if statement like this:


set -e

# Uncomment next line to see set -e effect:

if blubb; then
  echo "Command blubb was succesful."
  echo "Command blubb failed. Exit code: $?"
echo "Script exited normally."

It is possible to omit the "then" statement and use fewer lines:

if blubb; then :;
else echo "Command blubb failed. Exit code: $?"; fi
  • Another, even shorter, way to write the short form is: blubb || echo "Command blubb failed. Exit code: $?"
    – j3h
    Jan 7 at 17:59

Another approach, which I find fairly straightforward (and applies to other set options in addition to -e):

Make use of $- to restore settings.

For example:

set +e
# now '-e' is definitely disabled.
# do some stuff...

# Restore things back to how they were
set -$oldopt

Though for -e specifically, the options others have mentined (|| true or "put inside an if") may be more idiomatic.


I actually had a similar question recently (though I didn't post, I got around to it), and, from what I can see, it seems like just using set +e before the command and set -e afterward works most elegantly. Here's an example, grabbing the response of the command and not letting the error throw it away.


for argcol in $*
    args="${args} ${argcol}"
    set +e
    fortunevar=`fortune $args`
    set -e
} &> /dev/null
if [ $fortfail == 0 ]
    echo ${fortunevar}
    say ${fortunevar}
    echo misfortune: an illegal option was detected!
    echo misfortune: usage: misfortune [-afilosw] [-m pattern][ [#%] file/directory/all]

This grabs the output of 'fortune', checking its exit status, and echoes and says it. I think this is what you were asking for, or at least something similar? Anyway, hope this helps.

  • To clarify, the bit in curly parentheticals being redirected to /dev/null is what you're after, I believe. It makes the command have no ouput and checks its error status without exiting the program. Jul 14, 2015 at 15:31

I like to start subshell if want to change something temporarily. Below command demonstrates that first bad_command is ignored and second aborts execution.

bash -c 'set -e ;\
( set +e; bad_command ; echo still here ) ;\
echo even here ; \
bad_command ; \
echo but not here;'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.