Cria declare -a A
uma matriz vazia A
no bash ou apenas define um atributo no caso de A
ser 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 a saída esperada?
No Bash 4.3.48(1) recebo bash: A: unbound variable
ao consultar o número de elementos após declare
. Eu 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 gostaria de saber se declare
realmente define uma variável (estar vazia).
Isso depende se a variável correspondente já foi declarada no escopo atual (função global ou atual de nível superior) antes.
Se ela não foi declarada no escopo atual (e cuidado que no escopo de nível superior, a variável pode ter sido declarada (e atribuída) importando-a do ambiente), então ela a declara (torna-a 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
mostradeclare -a a
, nãodeclare -a a=()
como faria se você tivesse declarado e/ou atribuído coma=()
).Se já tivesse sido declarado no escopo atual (por exemplo, porque foi importado como uma variável escalar do ambiente quando no escopo global),
declare -a a
tentaria convertê -lo em um array.Se antes era um escalar, então se torna um
([0]=value-of-the-variable)
array. Se já era um array, ele é deixado intocado. Se fosse uma matriz associativa, falharia com umcannot convert associative to indexed array
erro.Observe que
declare a
não converteria uma matriz ou hash em escalar.bash
não seria capaz de converter um hash/array em escalar de qualquer maneira. Você pode usardeclare +aA a
para forçar um escalar (que falharia com um erro se a variável fosse anteriormente um hash/array 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 tentar expandi-la falha em
set -u
.Essa distinção entre dois estados declarados e atribuídos / conjuntos de uma variável não é específica para
bash
. Em POSIXsh
, você também podeexport
criar uma variável ou criá-lareadonly
sem dar um valor a ela.Observe que
unset
tanto desconfigura quanto não declara a variável. Embash
,mksh
eyash
pode restaurar a variável de um escopo externo.Em
zsh
, exceto nash
emulação, usingtypeset
on uma variável declara e a define como um valor vazio se já não estiver definido ou foi definido, mas de um tipo diferente (escalar vs array vs array associativo).