declare -a A
crea un array vuoto A
in bash, o semplicemente imposta un attributo nel caso A
è assegnato a dopo?
Considera questo codice:
set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}
Quale dovrebbe essere l'output previsto?
In Bash 4.3.48(1) ottengo bash: A: unbound variable
quando si interroga il numero di elementi dopo declare
.
Ricevo questo errore anche quando accedo a tutti gli elementi.
So che le versioni successive di Bash lo trattano in modo diverso.
Vorrei comunque sapere se declare
in realtà definisce una variabile (che deve essere vuota).
Risposta accettata:
Ciò dipende dal fatto che la variabile corrispondente sia già stata dichiarata nell'ambito corrente (di livello superiore, ovvero funzione globale o corrente).
Se non è stata dichiarata nell'ambito corrente (e attenzione che nell'ambito di livello superiore, la variabile potrebbe essere stata dichiarata (e assegnato) importandolo dall'ambiente), quindi lo dichiara (lo rende locale alla funzione quando è nell'ambito della funzione), assegnandole un tipo, ma non lo inizializza, nemmeno a una lista vuota (declare -p a
mostra declare -a a
, non declare -a a=()
come se lo avessi dichiarato e/o assegnato con a=()
).
Se era già stata dichiarata nell'ambito corrente (ad esempio perché è stata importata come variabile scalare dall'ambiente nell'ambito globale), allora declare -a a
proverei a convertire in un array.
Se in precedenza era uno scalare, diventa un ([0]=value-of-the-variable)
Vettore. Se era già un array, non viene toccato. Se era un array associativo, fallisce con un cannot convert associative to indexed array
errore.
Nota che declare a
non converte un array o un hash in scalare. bash
non sarebbe comunque in grado di convertire un hash/array in scalare. Puoi usare declare +aA a
per forzare uno scalare (che fallirebbe con un errore se la variabile fosse precedentemente un hash/array nell'ambito corrente).
Nel tuo caso, la variabile probabilmente non era già stata dichiarata nell'ambito corrente, quindi è stata dichiarata ma non assegnata, il che spiega perché provare ad espanderla non riesce in set -u
.
Quella distinzione tra due dichiarati e assegnato /imposta gli stati di una variabile non sono specifici di bash
. In POSIX sh
, puoi anche export
una variabile o rendila readonly
senza dargli un valore.
$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set
Nota che unset
annulla e annulla la dichiarazione della variabile. In bash
, mksh
e yash
può ripristinare la variabile da un ambito esterno.
In zsh
, tranne in sh
emulazione, utilizzando typeset
su una variabile dichiara e lo imposta su un valore vuoto se non era già impostato o era impostato ma di un tipo diverso (scalare vs array vs array associativo).