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.



One Reply
  1. 18

    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 di numbers (lasciando “due” “tre” nei prossimi due elementi). Per copiare come un array, utilizzare numbers=("${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”). Utilizzare for number in "${numbers[@]}" invece. In realtà, è bene prendere l’abitudine di mettere i doppi apici in praticamente tutte le variabili sostituzioni (ad esempio echo "${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…
    • No, non ce l’; ricontrollare come si sta usando.

Lascia un commento