Referências de nomes circulares na função shell bash, mas não no ksh

5

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".

    
por Kusalananda 10.08.2016 / 16:24

1 resposta

2

Chet Ramey (mantenedor do Bash) diz

There was extensive discussion about namerefs on bug-bash earlier this year. I have a reasonable suggestion about how to change this behavior, and I will be looking at it after bash-4.4 is released.

Enquanto isso, estou recorrendo a ofuscar um pouco os nomes das minhas variáveis nameref locais, para que elas não entrem em conflito com a biblioteca nem (esperançosamente) com nomes de variáveis de shell globais.

    
por 12.08.2016 / 17:39