
Cria declare -a A
um array vazio A
no bash ou apenas define um atributo caso A
seja atribuído posteriormente?
Considere este código:
set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}
Qual deve ser o resultado esperado?
No Bash 4.3.48(1) recebo bash: A: unbound variable
ao consultar o número de elementos após declare
. Também recebo esse erro ao acessar todos os elementos. Eu sei que as versões posteriores do Bash tratam isso de maneira diferente. Ainda assim, gostaria de saber se declare
realmentedefineuma variável (para estar vazia).
Responder1
Isso depende se a variável correspondente já foi declarada no escopo atual (nível superior, também conhecido como função global ou atual) antes.
Se não tiver sido declarada no escopo atual (e cuidado, pois no escopo de nível superior, a variável pode terdeclarado(e atribuído) importando-o do ambiente), então ele o declara (torna-o local para a função quando no escopo da função), atribuindo-lhe um tipo, mas não o inicializa, nem mesmo para uma lista vazia ( declare -p a
shows declare -a a
, não declare -a a=()
como seria se você tivesse declarado e/ou atribuído a=()
).
Se já tivesse sido declarado no escopo atual (por exemplo, porque foi importado como uma variável escalar do ambiente quando estava no escopo global), então declare -a a
tentariaconverterpara uma matriz.
Se anteriormente era um escalar, então se torna um ([0]=value-of-the-variable)
array. Se já era um array, ele permanece intacto. Se fosse uma matriz associativa, falharia com um cannot convert associative to indexed array
erro.
Observe que isso declare a
não converteria um array ou hash em escalar. bash
não seria capaz de converter um hash/array em escalar de qualquer maneira. Você pode usar declare +aA a
para forçar um escalar (que falharia com um erro se a variável fosse anteriormente um hash/matriz no escopo atual).
No seu caso, a variável provavelmente ainda não foi declarada no escopo atual, então acabou declarada, mas não atribuída, o que explica por que a tentativa de expandi-la falhou em set -u
.
Essa distinção entre doisdeclaradoeatribuído/definirestados de uma variável não são específicos para bash
. No POSIX sh
, você também pode export
criar uma variável ou criá-la readonly
sem fornecer um valor.
$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set
Observe que unset
ambos cancelam a definição e declaram a variável. In bash
e mksh
pode yash
restaurar a variável de um escopo externo.
Em zsh
, exceto na sh
emulação, o uso typeset
de uma variável declara e define-a com um valor vazio se ainda não estiver definido ou tiver sido definido, mas de um tipo diferente (escalar vs array vs array associativo).