Melhor com exemplos:
$ bash -c 'a=0; f() { local -i a=1; unset a; typeset -p a; a=2; }; f; echo "$a"'
declare -- a
0
Isso é unset
chamado em uma variável declarada no mesmo escopo. Está completamente desfeito. Ainda é declarado (embora tenha perdido atributos e valor), ainda é limitado a esse escopo. Você vê que, embora façamos um a=2
, isso ainda é feito em um a
local para f
, aquele do escopo externo não é afetado. Isso é bom e o que queremos.
Em:
$ ./bash -c 'a=0; f() { local a=1; g; a=2; }; g() { unset a; echo "$a"; }; f; echo "$a"'
0
2
Você pode ver que unset a
não desatou a
. Em vez disso, revelou o que está embaixo, aquele do escopo externo. Quando g
retornar, a variável f
a
não será mais local.
Note que é ainda pior em mksh
e yash
, em que unset
faz isso popping em vez de cancelar a definição mesmo para variáveis que foram declaradas no mesmo escopo. O primeiro exemplo com eles dá:
typeset a=0
2
Mais leituras em: