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 # this will probably change behavior; export shouldn't behave like this when # not in posix mode and the sequencing is probably wrong in posix mode. since # export is a special builtin, the variable assignment should modify the # global variable, leaving the local variable unchanged. all shells, including # bash, modify the local variable; bash is the only one that propagates the # value out to the calling environment. bash does that only when in posix # mode. func() { local var=inside var=value export var echo -n 'inside: ' ; declare -p var } var=outside 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 # test whether or not temporary environment assignments are exported # in posix mode showfoo() { printf %s "foo=${foo-}" echo -n ' environment foo=' printenv foo || echo } unset foo showfoo foo=foo showfoo showfoo unset -v foo unset -f showfoo