Skip to content

finally

When discovering Bash one of the missing features is not try catch block, but try finally.

The issue with trap is that: - I add trap signals every time different trap 'rm -rf "$tmpf"' 1 2 3 or EXIT or SIGINT? - I cannot append to the trap, which makes conditional logic really hard. Usually I end up creating all temporary files on top of the script just to have one trap for them all. - I cannot stop traps. I would want to trap execute when I stop using the resource, but - trap EXIT executes on the end of the script - trap RETURN no one knows when will execute and might execute on every RETURN from every function everywhere forever.

I do not really need "try catch". I need "try finally". I need cleanup. Thus the L_finally library came alive.

The L_finally <action> call: - Registers the action to execute on EXIT, SIGINT and SIGTERM. - The action will execute only once and only in the current process id, not anywhere or anytime else. - The option -r will add the action to execute on RETURN and will also set -o functrace. - It will only execute on RETURN from the current function in the current file which called the L_finally function. - If the action has been executed on RETURN, then it will not execute on EXIT. - If you happen to EXIT before getting to RETURN, the action still will be executed on EXIT. - Multiple calls append the actions to execute in reverse order.

Additionally, the L_finally_pop will execute and remove the last registered action.

Example:

#!/bin/bash
. L_lib.sh L_argparse \
  -- --option \
  ---- "$@"

tmpf=$(mktemp)
L_finally rm -rf "$tmpf"
: do something to tmpf >"$tmpf"

if [[ -n "$option" ]]; then
  tmpf2=$(mktemp)
  L_finally rm -rf "$tmpf2"
  : we need another tmpf2 >"$tmpf2"
  : it is ok, we can remove it now
  L_finally_pop
if

# tmp will be removed on the end of the script.

Function auto cleanup:

some_function() {
  local tmpf=$(mktemp)
  L_finally -r rm -rf "$tmpf"
  echo Do something with temporary file >"$tmpf"

  # exit 1    # this would remove the tempfile
  # return 1  # this would also remove the tempfile
  # the tempfile is automatically removed on the end of function
}

The action will register itself to EXIT and signals. The idea is, that you should be able to still hook your own custom action.

finally

L_finally

Register an action to be executed upon termination.

Options:

  • -r

    Set -o functrace and register the action to be executed on RETURN trap.

           Effectively this will execute the action on return from current function.
    
  • -s <int>

    The RETURN trap handler will execute the action only if called from

           the nth position in the stack relative to the current position. (default: 0)
    
  • -l

    Add action to be executed last, not first of the stack.

           Do not use L_finally_pop after it.
    

Argument: $@

Command to execute.

The command may not be return. It will just return from the handler function.

See: L_finally_pop

L_finally_pop

Execute and unregister the last action registered with L_finally

See: L_finally