set -o posix fn() { foo=abc : ; typeset +x foo; printenv|grep ^foo=; } fn unset -v foo unset -f fn func1() { var=1 var=2 : # or 'var=2 return', or another special builtin unset -v var echo $FUNCNAME: var = $var } func2() { func1 unset -v var # bug: fails silently } func1 echo ${var+"BUG: still set 1"} unset var func2 echo ${var+"BUG: still set 2"} unset -v var unset -f func1 func2 fn() { foo=abc : ; typeset +x foo; echo -n 'inside: ' ; declare -p foo; } fn echo outside: declare -p foo unset -v foo unset -f fn func() { var=value declare -x var echo -n 'inside: ' ; declare -p var } var=one func echo -n 'outside: ' ; declare -p var unset -v var unset -f func func() { local var=local var=global : echo -n 'inside: ' ; declare -p var } var=outside func echo -n 'outside: ' ; declare -p var unset -v var unset -f func