Skip to main content
switched for a better answer
Source Link
Reinstate Monica
  • 733
  • 1
  • 10
  • 24

I've tried the following code; I'm not sure if it solves all the problems you've mentioned or not. To use itI can't find this documented anywhere, you call but it seems like adding:

ontrap -return RETURN and pass the cleanup code 

as the first argumentlast command in the trap handler, rather than usingcauses the trap to revert to the previous one (trapbash directly.

function on-return-handler () {
        if [[ ${RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]} != ${#FUNCNAME[@]} ]]; then return; fi
        eval "${RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]}"
        unset RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]
        unset RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]
}

function on-return () {
        trap 'on-return-handler' RETURN
        RETURN_TRAP_STACK+=( "$1" )
        RETURN_TRAP_DEPTH+=( "${#FUNCNAME[@]}" )
}

This uses twois keeping a stack of bashRETURN arrays as stacks, one to store the cleanup code, and one to track the function call depth;handlers somewhere. The call depth is compareddocumentation says that in general trap - {SIGSPEC} causes the return handlertrap to make sure that we only firerevert to the clean updefault; I guess in the actual function that registered it. The values are 'popped' fromthis case, the stack afterdefault is the handler fires'shadowed' trap command.

I've tried the following code; I'm not sure if it solves all the problems you've mentioned or not. To use it, you call on-return and pass the cleanup code as the first argument, rather than using trap directly.

function on-return-handler () {
        if [[ ${RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]} != ${#FUNCNAME[@]} ]]; then return; fi
        eval "${RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]}"
        unset RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]
        unset RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]
}

function on-return () {
        trap 'on-return-handler' RETURN
        RETURN_TRAP_STACK+=( "$1" )
        RETURN_TRAP_DEPTH+=( "${#FUNCNAME[@]}" )
}

This uses two bash arrays as stacks, one to store the cleanup code, and one to track the function call depth; The call depth is compared in the return handler to make sure that we only fire the clean up in the actual function that registered it. The values are 'popped' from the stack after the handler fires.

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.

add explanation
Source Link
Reinstate Monica
  • 733
  • 1
  • 10
  • 24

I've tried the following code; I'm not sure if it solves all the problems you've mentioned or not. To use it, you call on-return and pass the cleanup code as the first argument, rather than using trap directly.

function on-return-handler () {
        if [[ ${RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]} != ${#FUNCNAME[@]} ]]; then return; fi
        eval "${RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]}"
        unset RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]
        unset RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]
}

function on-return () {
        trap 'on-return-handler' RETURN
        RETURN_TRAP_STACK+=( "$1" )
        RETURN_TRAP_DEPTH+=( "${#FUNCNAME[@]}" )
}

This uses two bash arrays as stacks, one to store the cleanup code, and one to track the function call depth; The call depth is compared in the return handler to make sure that we only fire the clean up in the actual function that registered it. The values are 'popped' from the stack after the handler fires.

I've tried the following code; I'm not sure if it solves all the problems you've mentioned or not. To use it, you call on-return and pass the cleanup code as the first argument, rather than using trap directly.

function on-return-handler () {
        if [[ ${RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]} != ${#FUNCNAME[@]} ]]; then return; fi
        eval "${RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]}"
        unset RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]
        unset RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]
}

function on-return () {
        trap 'on-return-handler' RETURN
        RETURN_TRAP_STACK+=( "$1" )
        RETURN_TRAP_DEPTH+=( "${#FUNCNAME[@]}" )
}

I've tried the following code; I'm not sure if it solves all the problems you've mentioned or not. To use it, you call on-return and pass the cleanup code as the first argument, rather than using trap directly.

function on-return-handler () {
        if [[ ${RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]} != ${#FUNCNAME[@]} ]]; then return; fi
        eval "${RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]}"
        unset RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]
        unset RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]
}

function on-return () {
        trap 'on-return-handler' RETURN
        RETURN_TRAP_STACK+=( "$1" )
        RETURN_TRAP_DEPTH+=( "${#FUNCNAME[@]}" )
}

This uses two bash arrays as stacks, one to store the cleanup code, and one to track the function call depth; The call depth is compared in the return handler to make sure that we only fire the clean up in the actual function that registered it. The values are 'popped' from the stack after the handler fires.

Source Link
Reinstate Monica
  • 733
  • 1
  • 10
  • 24

I've tried the following code; I'm not sure if it solves all the problems you've mentioned or not. To use it, you call on-return and pass the cleanup code as the first argument, rather than using trap directly.

function on-return-handler () {
        if [[ ${RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]} != ${#FUNCNAME[@]} ]]; then return; fi
        eval "${RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]}"
        unset RETURN_TRAP_STACK[${#RETURN_TRAP_STACK[@]}-1]
        unset RETURN_TRAP_DEPTH[${#RETURN_TRAP_DEPTH[@]}-1]
}

function on-return () {
        trap 'on-return-handler' RETURN
        RETURN_TRAP_STACK+=( "$1" )
        RETURN_TRAP_DEPTH+=( "${#FUNCNAME[@]}" )
}