declare -r
faz uma variável readonly mas também declara no escopo atual e assim torna-a local para a função atual. Você quer o readonly
em vez disso, apenas o primeiro:
readonly_once() {
local __assign
for __assign do
[[ -v ${__assign%%=*} ]] || readonly "$__assign"
done
}
Para ser usado como:
readonly_once VAR1=foo VAR2="$(cmd)" PATH ...
Observe que, desde que contrário a readonly
, esse readonly_once
não é uma palavra-chave (sim, readonly
é também uma palavra-chave, embora bash
mantenha esse fato oculto), $(cmd)
precisa ser citado para evitar split + glob, não é uma atribuição nesse ponto.
$(cmd)
será expandido (e assim cmd
run), mesmo que o valor acabe não sendo atribuído a VAR2
se já tiver sido definido.
Essa função só funciona para variáveis escalares, não matrizes nem matrizes associativas.