Skip to content

Instantly share code, notes, and snippets.

@phemmer
Last active March 5, 2024 09:55
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save phemmer/e943dce38eaa948f1893d9392741970f to your computer and use it in GitHub Desktop.
Save phemmer/e943dce38eaa948f1893d9392741970f to your computer and use it in GitHub Desktop.
bash defer function - just like go's defer()
function _run_deferred() {
local _depth="$BASHPID.${#FUNCNAME[@]}"
[[ "$_depth" != "$_deferred_depth" ]] && return
local opt=$-
set +e
for (( i=${#_deferred[@]} - 1; i >= 0; i-- )); do
eval "${_deferred[i]}"
done
[[ "$opt" == *e* ]] && set -e
}
function _defer() {
_deferred_depth="$BASHPID.${#FUNCNAME[@]}"
_deferred+=( "$(printf '%q ' "$@")" )
}
# This has to be an alias so that the `trap ... RETURN` runs appropriately.
shopt -s expand_aliases
alias defer='declare -a _deferred; declare _deferred_depth; trap _run_deferred EXIT RETURN; _defer'
function foo1() { echo foo1; }
function foo2() { defer echo foo2; foo1; }
function foo3() { foo2; }
function foo4() { echo foo4-begin; ( defer echo foo4-subshell; foo3; ); echo foo4-end; }
foo4
foo4-begin
foo1
foo2
foo4-subshell
foo4-end
@lrobot
Copy link

lrobot commented Sep 27, 2023

amaze craft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment