4 ms·
Just use: if command -v command >/dev/null 2>&1 then command -v local >/dev/null 2>&1 || alias local=typeset fi eval "__fn=;__
by alganet 2y ago
Just use:
if command -v command >/dev/null 2>&1
then command -v local >/dev/null 2>&1 || alias local=typeset
fi
eval "__fn=;__fn(){ local __fn=leak;};__fn || :;"
if test -n "$__fn"
then echo local leaks here!
fi
It will not crash on posh because I'm being tricky with eval and command. posh supports local variable scope.
The only shell partially missing local support is ksh, but it has a gotcha. It works if the function is declared with the `function` keyword. All you have to do is use ksh's own tools to redeclare all functions automatically:
__list=$(typeset +f)
IFS="$__eol" # __eol should have a line break
for __decl in $__list
do
__name=${__decl%" #"*}
__name=${__name%"()"}
__body="$(typeset -f "$__name" || :)"
eval "function $__name ${__body#"$__decl"}"
done
IFS=" "
Of course, for this to work, all functions must be loaded before running and any declared after the fix will not be local, which is a good idea anyway. I always put the alias polyfill on the header of my library and the eval/for polyfill just before invoking my main function.
There is still an inconsistency with default local values. To get the same behavior everywhere, always initialize local variables
THIS IS FINE:
local foo=;
local foo=bar;
THIS CAN INHERIT WEIRD STUFF:
local foo;
Done, you have portable bourne sh scope everywhere imaginable.