2012-05-02 27 views
16

W bashie, gdy uzyskuję dostęp do tablicy według indeksu, otrzymuję dziwne zachowanie, jeśli tablica jest zmienną zaimportowaną w źródle innego skryptu bash . Co powoduje to zachowanie? Jak można to naprawić, aby tablica pochodząca z innego skryptu Basha zachowywała się w taki sam sposób, jak tablica zdefiniowana z działającego skryptu?Dostęp do tablicy przez index w bashie nie działa poprawnie, jeśli tablica pochodzi z pliku źródłowego

$ {numery [0]} evals do "Raz dwa trzy", a nie "jeden", jak to should.The pełny test Starałem się wykazać, to zachowanie jest pokazany poniżej:

Źródło testu. 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 

Źródło number.sh:

#!/bin/bash 
#Numbers 

sourced_numbers=(one two three) 

Wyjście 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

Może debugowanie powłoki za pomocą 'set -vx' pokaże ci coś. (Nie masz czasu na eksperymenty teraz). Powodzenia. – shellter

Odpowiedz

16

Problem nie ma nic wspólnego z pozyskiwaniem; dzieje się tak, ponieważ zadanie numbers=${sourced_numbers[@]} nie robi tego, co myślisz. Konwertuje tablicę (sourced_numbers) na prosty łańcuch i przechowuje ją w pierwszym elemencie z numbers (pozostawiając "dwa" "trzy" w dwóch kolejnych elementach). Aby skopiować go jako tablicę, użyj zamiast tego numbers=("${sourced_numbers[@]}").

BTW, for number in ${numbers[@]} to niewłaściwy sposób na przechodzenie przez elementy tablicy, ponieważ spowoduje to przełamanie białych znaków w elementach (w tym przypadku tablica zawiera "jeden dwa trzy" "dwa" "trzy", ale pętla działa dla "jeden", "dwa", "trzy", "dwa", "trzy"). Zamiast tego użyj for number in "${numbers[@]}". Właściwie dobrze jest wejść w zwyczaj podwójnego cytowania prawie wszystkie zmienne substytucje (np. echo "${numbers[${i}]}"), ponieważ nie jest to jedyne miejsce, w którym pozostawienie ich niecytowanych może spowodować kłopoty.

+0

'dla liczby w" $ {numbers [@]} "' również przerwać białe znaki ... – shinzou

+0

@kuhaku Nie, nie ma; ponownie sprawdź, jak go używasz. –

Powiązane problemy