#!/bin/bash CLEANUP= CLEANUP_INDEX=1 CLEANUP_LEVEL=0 push_cleanup() { CLEANUP="$1 $CLEANUP" shift local i=1 local arg for arg do eval CLEANUP_${CLEANUP_INDEX}_ARG$i=\"\$arg\" i=$((i+1)) done eval CLEANUP_${CLEANUP_INDEX}_ARGNUM=$(($i-1)) CLEANUP_INDEX=$((CLEANUP_INDEX+1)) } pop_cleanup() { cleanup=$(echo "$CLEANUP" | $SED -e "s/^\([^[:space:]]*\).*/\1/") CLEANUP=$(echo "$CLEANUP" | $SED -e "s/^[^[:space:]]*[[:space:]]*\(.*\)/\1/") CLEANUP_INDEX=$((CLEANUP_INDEX-1)) if [ -n "$1" ] then local args= eval local argnum=\$CLEANUP_${CLEANUP_INDEX}_ARGNUM local i for i in $(seq 1 $argnum) do eval local arg=\$CLEANUP_${CLEANUP_INDEX}_ARG$i args+="\"$arg\" " done CLEANUP_LEVEL=$((CLEANUP_LEVEL+1)) eval $cleanup $args CLEANUP_LEVEL=$((CLEANUP_LEVEL-1)) fi } run_cleanups() { while [ -n "$CLEANUP" ] do pop_cleanup 1 done } trap run_cleanups EXIT