2012-05-02 4 views
16

In bash, wenn ich auf ein Array nach Index zugreifen, bekomme ich seltsames Verhalten, wenn das Array eine Variable ist, die in der Quelle eines anderen Bash-Skript importiert wurde . Was verursacht dieses Verhalten? Wie kann es behoben werden, so dass sich ein Array, das von einem anderen Bash-Skript stammt, genauso verhält wie ein Array, das im laufenden Skript definiert ist?Zugriff auf Array nach Index in bash funktioniert nicht korrekt, wenn Array aus einer Quelle stammt

Quelle des Tests:

$ {Zahlen [0]} evals auf „eins zwei drei“ und nicht „eines“, wie es in vollen Test should.The Ich habe versucht, dieses Verhalten zu zeigen, ist unten dargestellt. 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 

Quelle von number.sh:

#!/bin/bash 
#Numbers 

sourced_numbers=(one two three) 

Ausgabe von 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 
+0

vielleicht Shell-Debugging mit 'set-vx' wird Ihnen etwas zeigen. (Habe jetzt keine Zeit zum Experimentieren). Viel Glück. – shellter

Antwort

16

Das Problem hat nichts mit Sourcing zu tun; es passiert, weil die Aufgabe numbers=${sourced_numbers[@]} nicht tut, was Sie denken, dass es tut. Er konvertiert das Array (sourced_numbers) in eine einfache Zeichenfolge und speichert diese im ersten Element von numbers (wobei in den nächsten beiden Elementen "zwei" "drei" übrig bleiben). Um es als Array zu kopieren, verwenden Sie stattdessen numbers=("${sourced_numbers[@]}").

BTW, for number in ${numbers[@]} ist die falsche Methode, um die Elemente eines Arrays zu durchlaufen, weil es in Leerzeichen in den Elementen bricht (in diesem Fall enthält das Array "eins zwei drei" "zwei" "drei", aber das Schleife läuft für "eins", "zwei", "drei", "zwei", "drei". Verwenden Sie stattdessen for number in "${numbers[@]}". Eigentlich ist es gut, sich die Angewohnheit zu nehmen, so ziemlich alle variablen Substitutionen doppelt zu zitieren (z. B. echo "${numbers[${i}]}"), da dies nicht der einzige Ort ist, an dem das Nichtangeben von ihnen Probleme verursachen könnte.

+0

'für die Nummer in" $ {numbers [@]} "' auch whitespaces brechen ... – shinzou

+0

@kuhaku Nein tut es nicht; überprüfen Sie erneut, wie Sie es verwenden. –

Verwandte Themen