Подтвердить что ты не робот

Доступ к массиву по индексу в bash не работает корректно, если массив из исходного файла

В bash, когда я обращаюсь к массиву по индексу, я получаю странное поведение, если массив является переменной, которая была импортирована в источник другого сценария bash. Что вызывает такое поведение? Как это можно исправить, так что массив, полученный из другого сценария bash, ведет себя так же, как массив, определенный из сценария запуска?

$ {numbers [0]} имеет значение "один два три", а не "один", как и следовало бы. Полный тест, который я попытался продемонстрировать, показан ниже:

Источник 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

Источник number.sh:

#!/bin/bash
#Numbers

sourced_numbers=(one two three)

Вывод 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
4b9b3361

Ответ 1

Проблема не имеет ничего общего с поиском; это происходит потому, что numbers=${sourced_numbers[@]} присваивания numbers=${sourced_numbers[@]} не делают то, что вы думаете. Он преобразует массив (sourced_numbers) в простую строку и сохраняет это в первом элементе numbers (оставляя "два" "три" в следующих двух элементах. Чтобы скопировать его как массив, используйте numbers=("${sourced_numbers[@]}").

BTW, for number in ${numbers[@]} - это неправильный способ циклического перемещения элементов массива, поскольку он будет разбиваться на пробелы в элементах (в этом случае массив содержит "один два три" "два", три ", но цикл работает для" один "," два "," три "," два "," три "). Вместо этого используйте for number in "${numbers[@]}". На самом деле, хорошо привыкнуть к двойному цитированию почти всех переменных подстановок (например, echo "${numbers[${i}]}"), так как это не единственное место, где оставлять их без кавычек может вызвать проблемы.