184

I'm building a Shell Script that has a if function like this one:

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias
then
    echo $jar_file signed sucessfully
else
    echo ERROR: Failed to sign $jar_file. Please recheck the variables
fi

...

I want the execution of the script to finish after displaying the error message. How I can do this?

Bondolin
  • 2,793
  • 7
  • 34
  • 62
Nathan Campos
  • 28,769
  • 59
  • 194
  • 300

4 Answers4

365

If you put set -e in a script, the script will terminate as soon as any command inside it fails (i.e. as soon as any command returns a nonzero status). This doesn't let you write your own message, but often the failing command's own messages are enough.

The advantage of this approach is that it's automatic: you don't run the risk of forgetting to deal with an error case.

Commands whose status is tested by a conditional (such as if, && or ||) do not terminate the script (otherwise the conditional would be pointless). An idiom for the occasional command whose failure doesn't matter is command-that-may-fail || true. You can also turn set -e off for a part of the script with set +e.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 5
    According to http://mywiki.wooledge.org/BashFAQ/105 - this feature has a history of being obscure and convoluted in its determination of which commands' error codes cause an automatic exit. Furthermore, "the rules change from one Bash version to another, as Bash attempts to track the extremely slippery POSIX definition of this 'feature'". I agree with @Dennis Williamson and the accepted answer of http://stackoverflow.com/questions/19622198/what-does-set-e-mean-in-a-bash-script - use trap 'error_handler' ERR. Even if it's a trap! – Bondolin Nov 09 '15 at 14:06
  • 3
    often using the `-x` flag with the `-e` flag is enough of a trace on where your program is on exit. That implies that the user of the script is also the developer. – Alexander Oh Jul 25 '16 at 12:05
  • Nice but I think the OP needed to exit the script from a self-defined exception. – vdegenne Jan 27 '20 at 12:32
196

Are you looking for exit?

This is the best bash guide around. http://tldp.org/LDP/abs/html/

In context:

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias
then
    echo $jar_file signed sucessfully
else
    echo ERROR: Failed to sign $jar_file. Please recheck the variables 1>&2
    exit 1 # terminate and indicate error
fi

...
MattBianco
  • 1,501
  • 2
  • 20
  • 30
Byron Whitlock
  • 52,691
  • 28
  • 123
  • 168
  • 6
    If you like the ABS, you'll love the [BashGuide](http://mywiki.wooledge.org/BashGuide), [BashFAQ](http://mywiki.wooledge.org/BashFAQ) and [BashPitfalls](http://mywiki.wooledge.org/BashPitfalls). – Dennis Williamson Dec 08 '10 at 04:45
  • Those Bash links are AWESOME! The BashFAQ would be better positioned as BashRecipes. – Pete Alvin Dec 29 '19 at 20:55
46

If you want to be able to handle an error instead of blindly exiting, instead of using set -e, use a trap on the ERR pseudo signal.

#!/bin/bash
f () {
    errorCode=$? # save the exit code as the first thing done in the trap function
    echo "error $errorCode"
    echo "the command executing at the time of the error was"
    echo "$BASH_COMMAND"
    echo "on line ${BASH_LINENO[0]}"
    # do some error handling, cleanup, logging, notification
    # $BASH_COMMAND contains the command that was being executed at the time of the trap
    # ${BASH_LINENO[0]} contains the line number in the script of that command
    # exit the script or return to try again, etc.
    exit $errorCode  # or use some other value or do return instead
}
trap f ERR
# do some stuff
false # returns 1 so it triggers the trap
# maybe do some other stuff

Other traps can be set to handle other signals, including the usual Unix signals plus the other Bash pseudo signals RETURN and DEBUG.

dutoitns
  • 1,949
  • 1
  • 26
  • 32
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
13

Here is the way to do it:

#!/bin/sh

abort()
{
    echo >&2 '
***************
*** ABORTED ***
***************
'
    echo "An error occurred. Exiting..." >&2
    exit 1
}

trap 'abort' 0

set -e

# Add your script below....
# If an error occurs, the abort() function will be called.
#----------------------------------------------------------
# ===> Your script goes here
# Done!
trap : 0

echo >&2 '
************
*** DONE *** 
************
'
supercobra
  • 15,810
  • 9
  • 45
  • 51