Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Propagating exit code to caller in case of a shell error from script having an exit trap

Is it possible to propagate an exit code to the caller in case of a syntax error in a Bash script with an EXIT trap? For example, if I have:

#! /bin/bash

set -eu

trap "echo dying!!" EXIT

echo yeah
echo $UNBOUND_VARIABLE
echo boo

Then, running it gives an exit code 0 even if the script did not really end successfully:

$ bash test.sh
yeah
test.sh: line 8: UNBOUND_VARIABLE: unbound variable
dying!!

$ echo $?
0

But if I comment out the exit trap, the script returns 1. Alternatively, if I replace the line with the unbound variable with a command that returns nonzero (e.g. /bin/false), that exit value is propagated as I would like it to.

like image 658
Eemeli Kantola Avatar asked Jul 31 '14 16:07

Eemeli Kantola


People also ask

How do you exit a script in shell script?

To end a shell script and set its exit status, use the exit command. Give exit the exit status that your script should have. If it has no explicit status, it will exit with the status of the last command run.

What is the correct command to remove the files using trap and quit in case of any failure?

Any commands above the trap can exit and not be caught in the trap. Now if the script exits for any reason, it will still run the rm command to delete the file. Here is an example of me sending SIGINT (CTRL+C) to interrupt the script while it is running.


2 Answers

The shell exits with the result of the last executed command. In your trap case, that's echo, which usually returns with success.

To propagate your value, simply exit with it.

#!/bin/bash

set -eu

die() {
  echo "Dying!!"
  exit "$1"
}

trap 'die $?' EXIT

echo yeah
echo $unbound
echo boo

Also note that set -e is considered harmful -- it makes you think the script will exit if a command fails, which it won't always do.

like image 59
that other guy Avatar answered Sep 20 '22 01:09

that other guy


This behavior is related to different Bash versions. The original script works as expected on Bash 4.2 but not on 3.2. Having the error-prone code in a separate script file and running it in a subshell works around problems in earlier Bash versions:

#!/bin/bash

$BASH sub.sh
RETVAL=$?

if [[ "$RETVAL" != "0" ]]; then
  echo "Dying!! Exit code: $RETVAL"
fi

sub.sh:

set -eu

echo yeah
echo $UNBOUND_VARIABLE
echo boo
like image 30
Eemeli Kantola Avatar answered Sep 19 '22 01:09

Eemeli Kantola