15

Let's say you have a shell script that runs some sort of cleanup code via an EXIT trap, like this:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

trap mytrap exit

echo I am at the end of the script.

This will, as expected, print out It's a trap! when the script exits:

$ sh myscript
I am at the end of the script.
It's a trap!

You modify the script to add a function that generates some output that ultimately gets piped to another command, like this:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

myfunc () {
  echo "I've got a bad feeling about this..."
}

trap mytrap exit

myfunc | cat > /dev/null

echo I am at the end of the script.

Because of the pipe, the code in myfunc is run in a subshell...and subshells don't appear to inherit the trap behavior of the parent, which means if you perform any actions here that should be cleaned up by your trap code that won't happen.

So you try this:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
}

And it still fails to trigger mytrap when the subshell exits. It turns out that you need an explicit exit, like this:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
  exit
}

With the above code, mytrap will trigger appropriately upon exit from the subshell:

$ sh myscript 
It's a trap!
I am at the end of the script.
It's a trap!

Is that expected behavior? I was surprised by several things here:

  • trap settings weren't inherited by subshells
  • implicit exit from a subshell does not appear to trigger an EXIT trap
2
  • Implicit exit from a subshell triggers EXIT trap in some other shells such as dash and lksh. It triggers EXIT trap even in bash, if you have set set -e and some command in the subshell exits with non-zero status (like e.g. false). I wonder, if the behavior is somehow ruled by POSIX?
    – jarno
    Apr 30, 2021 at 20:36
  • See also my related question
    – jarno
    Apr 30, 2021 at 20:52

1 Answer 1

8

The bash trap builtin allows the keyword RETURN. Hence change:

trap mytrap EXIT

to:

trap mytrap RETURN

See the discussion of trap in shell-builtins

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .