1

Is there a way to disable a trap within the trap handler?

I'd like to simplify some code by using the RETURN trap. my_func will return the value of my_command. The tmpfile will be cleaned up as my_func returns. This technique would allow me to avoid assigning a temp var to hold $? from my_func while I do cleanup.

However, I'm unable to reset the trap handler within the handler and cleanup is now invoked after every function return.

Ultimately what I really want to do is cleanup after my_command is invoked but still have it as the last command so the return value is implicit. Any suggested alternatives would be appreciated.

cleanup() { # generic cleanup w/ reset
   "$@"
   trap - RETURN
}

my_func() {
   local -r tmpfile="/tmp/tmpfile"
   trap "cleanup rm ${tmpfile}" RETURN
   my_command -f ${tmpfile}
}

caller() {
   if my_func ; then
      do_success_ops
   fi
}
Cyrus
  • 84,225
  • 14
  • 89
  • 153
Raster
  • 157
  • 1
  • 2
  • 7
  • Note that this is a Bash-specific issue; in Zsh for example, you can reset the trap in trap handler. I use this trick to recover `INT` traps. (`RETURN` is called `EXIT` in Zsh, and it’s *local*, so you don’t even need to clean-up the trap itself.) – Franklin Yu Oct 19 '20 at 01:07

1 Answers1

1

I always use this pattern:

trap 'rm -rf "$workspace"' EXIT
workspace="$(mktemp --directory)" # Or -d
# Use $workspace

This has several nice features:

  1. The trap is set up before creating the directory, so there is no race condition.
  2. Creating a directory means I shouldn't need any more mktemp calls in the script, because I can just put everything in that directory.
  3. Creating a directory rather than a file gives a better security baseline, because it's common that everyone can see what's directly in /tmp, but a new directory will be owned by you and will be created "u+rwx, minus umask restrictions" (from man mktemp).

If you want to clean up earlier I would recommend just doing it explicitly. Your solution has two unnecessary levels of indirection: the trap and the passing of arguments to be run.

l0b0
  • 55,365
  • 30
  • 138
  • 223
  • Thanks for the response. I do, in fact, use this temp directory pattern already, it is very useful. The example is just a simple excerpt of a much larger script. The cleanup function is intended to run anything (and maybe do much more than just removing a file). For example, at times I need to clear the screen (but I don't want the screen cleared after every function exit). The essence of my question is if there is something akin to a finally block in Java. Please don't be concerned about what the cleanup code is actually doing. – Raster Oct 17 '18 at 14:27