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
Best Answer
The bash
trap
builtin allows the keywordRETURN
. Hence change:to:
See the discussion of
trap
in shell-builtins