Eu estou escrevendo um conjunto de funções de shell que eu quero ter trabalhando tanto no Bash quanto no KornShell93, mas com o Bash eu estou correndo em um aviso de "referência de nome circular".
Esta é a essência do problema:
function set_it {
typeset -n var="$1"
var="hello:$var"
}
function call_it {
typeset -n var="$1"
set_it var
}
something="boff"
call_it something
echo "$something"
Executando:
$ ksh script.sh
hello:boff
$ bash script.sh
script.sh: line 4: warning: var: circular name reference
hello:
O KornShell93 faz exatamente o que eu quero, mas o Bash falha, e também avisa sobre a mesma coisa na linha 2 se a variável something
no script é nomeada var
.
Eu gostaria que a variável var
fosse local para cada função, e é por isso que uso typeset
, mas o Bash não parece gostar de "desreferenciar" um nameref para uma variável com o mesmo nome o nameref em si. Eu não posso usar local -n
ou declare -n
, pois isso iria quebrar em ksh
que não tem, e mesmo se eu o fizesse, não resolveria o problema.
A única solução que encontrei é usar nomes de variáveis exclusivos em cada função , o que parece um pouco bobo, já que eles são locais.
O manual do Bash diz o seguinte sobre typeset
:
typeset
[...]
-n
Give each name the nameref
attribute, making it a name
reference to another variable. That other variable is
defined by the value of name
. All references and
assignments to name
, except for changing the -n
attribute itself, are performed on the variable referenced by name's value.
[...]
When used in a function, declare
and typeset
make each name
local, as with the local
command, unless the -g
option is
supplied. If a variable name is followed by =value
, the
value of the variable is set to value
.
É óbvio que há algo que não entendo sobre as referências de nomes e as variáveis de função locais do Bash.
Então, a pergunta é: neste caso, estou faltando alguma coisa sobre o tratamento de variáveis de referência de nome pelo Bash, ou isso é um bug / falta de funcionalidade no Bash?
Atualizar : Atualmente, estou trabalhando com GNU bash, version 4.3.39(1)-release (x86_64-apple-darwin15)
e com GNU bash, version 4.3.46(1)-release (x86_64-unknown-openbsd6.0)
. O Bash enviado com o OS X (3.2.57) não parece saber nada sobre as referências de nomes.
Atualizar : ainda mais curto:
function bug {
typeset -n var="$1"
printf "%s\n" "$var"
}
var="hello"
bug var
Resultados em bash: warning: var: circular name reference
. O var
na função deve ter um escopo diferente do var
no escopo global. Isso impõe uma restrição desnecessária ao chamador. A restrição é "você não tem permissão para nomear suas variáveis como quiser, porque pode haver um confronto de nome com um nameref (local) nesta função".