5

I am looking for an idiomatic pattern to use traps as a meaning "ensure" or "finally", so they should execute no matter how a bash function exits.

I've found the RETURN trap, but nesting that is not trivial. I guess the trap inside bar shadows the trap in foo. How can I set up traps for both foo and bar

So given the following code, I'd like to have cleanup when exiting foo and exiting bar.

My first attempt was to have a global string storing the cleanup tasks, but that one breaks whenever you have subshells. And it seems from the output of the following code, that RETURN signal is also "shell-global"

fooclear() { echo fooclear; }
barclear() { echo barclear; }
bar() {
  echo bar
  trap barclear RETURN INT ERR TERM EXIT
  sleep 1
}

foo() {
  echo foo
  sleep 1
  trap fooclear RETURN INT ERR TERM EXIT
  bar
}

for i in 1 2 3; do
  foo &
done
wait

And a warning: to avoid duplicate handling, one must somehow administer that a clearing function has already completed.

2 Answers 2

3

I can't find this documented anywhere, but it seems like adding:

trap - RETURN

as the last command in the trap handler, causes the trap to revert to the previous one (bash is keeping a stack of RETURN handlers somewhere. The documentation says that in general trap - {SIGSPEC} causes the trap to revert to the default; I guess in this case, the default is the 'shadowed' trap command.

1
  • It's more complex than this. Calling trap - [SIG_SPEC] doesn't revert to previous trap, it reverts to "the value it had upon entrance to the shell". This could be blank, or inherited from the parent shell. It wil not revert to one you previously set in the current shell. There is no trap stack other than that created each time you spawn a subshell. In other words if you set a trap for a given SIG_SPEC and then set it again the first one is replaced by the second.
    – benrifkah
    Sep 1, 2021 at 20:43
1

Correct, RETURN signal is shell-global, as are all of the signals. Trapping any signal replaces any trap already set on that signal which is probably what you mean by "shadows".

Traps afford some simple exception handling but for something more robust I'd check the answers to this stackoverflow question about TRY/CATCH

You must log in to answer this question.

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