13

This is myscript.sh:

#!/bin/bash

function mytrap {
    echo "Trapped!"
}
trap mytrap EXIT

exit 3

And when I run it:

> ./myscript.sh
echo $?
3

Why is the exit code of the script the exit code with the trap the same as without it? Usually, a function returns implicitly the exit code of the last command executed. In this case:

  1. echo returns 0
  2. I would expect mytrap to return 0
  3. Since mytrap is the last function executed, the script should return 0

Why is this not the case? Where is my thinking wrong?

codeforester
  • 39,467
  • 16
  • 112
  • 140
blueFast
  • 41,341
  • 63
  • 198
  • 344
  • 1
    Pro-tip: It's a good idea to always use `set -e` and 'set -o pipefail' in your bash scripts. That stops a script as soon as one command fails. It allows you to find errors earlier and abort before doing stupid things on half-baked state. – Hubert Grzeskowiak Dec 11 '17 at 10:07

1 Answers1

11

Look the reference from the below man bash page,

exit [n] Cause the shell to exit with a status of n. If n is omitted, the exit status is that of the last command executed. A trap on EXIT is executed before the shell terminates.

You have the debug version of the script to prove that,

+ trap mytrap EXIT
+ exit 3
+ mytrap
+ echo 'Trapped!'
Trapped!

Consider the same as you mentioned in your comments, the trap function returning an error code,

function mytrap {
    echo "Trapped!"
    exit 1
}

Look the expanded version of the script,

+ trap mytrap EXIT
+ exit 3
+ mytrap
+ echo 'Trapped!'
Trapped!
+ exit 1

and

echo $?
1

To capture the exit code on trap function,

function mytrap {
    echo "$?"
    echo "Trapped!"
}
Inian
  • 80,270
  • 14
  • 142
  • 161
  • So there are commands executed after exit? Can I run another exit? What will be the exit code of the script then? Will that cause an infinite trap loop? – blueFast Jan 12 '17 at 17:49
  • 2
    If you put an `exit 1` in your trap code, that would be the exit code of your script. – codeforester Jan 12 '17 at 17:50
  • @codeforester thanks. And it seems it does not retrigger the trap – blueFast Jan 12 '17 at 17:53
  • how do I know, in `mytrap` what is the exitcode that the script will be return? (assuming I do not overwrite it by calling `exit` again in the trap function) – blueFast Jan 12 '17 at 17:57
  • @blueFast in the trap function, check for the value of `$?`, that's always the exit code of the last command, including the one that caused the trap to be called. Moreover, `set -e` and `trap ERR` captures the event that causes the script to abort. – zakmck Jun 29 '21 at 22:42
  • 1
    (Late comment.) If you have `set -e` and your trap handler executes a command which returns a non-zero exit code (subject to the rules suppressing errors) while `set -e` is still in effect, then that exit code will be returned rather than exit code of the last statement of the exit handler, or the original exit code which triggered the handler. – leek Jul 25 '23 at 17:30