Uma convenção comum é usar todas as maiúsculas para variáveis de ambiente e todas as minúsculas para variáveis locais de script. Desta forma, uma variável local nunca colide com uma variável de ambiente.
Eu não acho que o zsh tenha uma opção para distinguir entre o valor local e o valor exportado de uma variável. Uma solução alternativa é salvar e restaurar o valor. Isso significa listar as variáveis que você deseja salvar.
run () {
typeset -A _saved_variables
_saved_variables[foo]=$foo _saved_variables[bar]=$bar
local foo='not seen' bar='not seen either'
…
foo=$_saved_variables[foo] bar=$_saved_variables[bar] bash print.sh
}
Se você quiser preservar todo o ambiente, poderá executar typeset -px
para imprimi-lo de forma analisável. Observe que isso não funcionará se você tiver exportado variáveis somente leitura; Para lidar com esse caso, você precisaria passar pelos nomes das variáveis e selecionar apenas os que não são somente leitura.
run () {
_saved_variables='typeset -px'
local foo='not seen' bar='not seen either'
…
(eval $_saved_variables; exec bash print.sh)
}
Outra opção é estruturar seu script de maneira diferente. Determine o comando que você deseja executar em um subshell e imprima-o (adequadamente citado) para o pai executar.
run () {
# you can clobber variables here
…
printf %q "bash print.sh"
}
eval $(run)