L’accesso Array con indice in bash non funzionare correttamente se la matrice è da un file di provenienza
In bash quando ho accesso un array con indice di ottenere un comportamento strano se l’array è una variabile che è stata importata in origine di un altro script bash. Quali sono le cause di questo comportamento? Come può essere risolto in modo un array che proviene da un altro script bash si comporta allo stesso modo come una matrice definita dall’interno dello script?
${numeri[0]} evals di “uno due tre” e non “uno” come dovrebbe.Il test ho cercato di dimostrare questo comportamento è mostrato di seguito:
Fonte di test.sh :
#!/bin/bash
function test {
echo "Length of array:"
echo ${#numbers[@]}
echo "Directly accessing array by index:"
echo ${numbers[0]}
echo ${numbers[1]}
echo ${numbers[2]}
echo "Accessing array by for in loop:"
for number in ${numbers[@]}
do
echo $number
done
echo "Accessing array by for loop with counter:"
for (( i = 0 ; i < ${#numbers[@]} ; i=$i+1 ));
do
echo $i
echo ${numbers[${i}]}
done
}
numbers=(one two three)
echo "Start test with array from within file:"
test
source numbers.sh
numbers=${sourced_numbers[@]}
echo -e "\nStart test with array from source file:"
test
Fonte di number.sh :
#!/bin/bash
#Numbers
sourced_numbers=(one two three)
Uscita di test.sh :
Start test with array from within file:
Length of array:
3
Directly accessing array by index:
one
two
three
Accessing array by for in loop:
one
two
three
Accessing array by for loop with counter:
0
one
1
two
2
three
Start test with array from source file:
Length of array:
3
Directly accessing array by index:
one two three
two
three
Accessing array by for in loop:
one
two
three
two
three
Accessing array by for loop with counter:
0
one two three
1
two
2
three
- forse shell di debug con
set -vx
vi mostrerà qualcosa. (Non hanno il tempo di sperimentare, per ora). Buona fortuna.
Il problema non ha nulla a che fare con il sourcing; questo sta accadendo perché l’assegnazione
numbers=${sourced_numbers[@]}
non fare quello che tu pensi. Converte l’array (sourced_numbers
) in una stringa semplice, e negozi che, in un primo elemento dinumbers
(lasciando “due” “tre” nei prossimi due elementi). Per copiare come un array, utilizzarenumbers=("${sourced_numbers[@]}")
invece.BTW,
for number in ${numbers[@]}
è il modo sbagliato per scorrere un array di elementi, perché si romperà su spazi tra gli elementi (in questo caso, la matrice contiene “uno due tre” “due” “tre”, ma il loop viene eseguito per “uno”, “due”, “tre”, “due”, “tre”). Utilizzarefor number in "${numbers[@]}"
invece. In realtà, è bene prendere l’abitudine di mettere i doppi apici in praticamente tutte le variabili sostituzioni (ad esempioecho "${numbers[${i}]}"
), in quanto questo non è l’unico posto dove lasciare loro non quotate potrebbero causare problemi.for number in "${numbers[@]}"
inoltre di suddividere gli spazi bianchi…