Как передать массив в функцию bash

#arrays #bash #shell

#массивы #bash #оболочка

Вопрос:

Как мне передать массив функции, и почему это не сработало бы? Решения в других вопросах у меня не сработали. Для записи мне не нужно копировать массив, поэтому я не возражаю против передачи ссылки. Все, что я хочу сделать, это выполнить цикл над ним.

 $ ar=(a b c)
$ function test() { echo ${1[@]}; }
$ echo ${ar[@]}
a b c
$ test $ar
bash: ${1[@]}: bad substitution
$ test ${ar[@]}
bash: ${1[@]}: bad substitution
  

Ответ №1:

 #!/bin/bash
ar=( a b c )
test() {
    local ref=$1[@]
    echo ${!ref}
}

test ar
  

Комментарии:

1. Хорошо, это работает: test() { local ref=$ 1[@] для pkg в ${!ref}; выполнить echo «1 $ pkg 2» } ar=( a b c ) проверить ar

2. используйте for pkg in "${!ref}" , иначе цикл будет хрупким по отношению к пробелам в элементах массива (например, ar=(a "b c" d) ).

Ответ №2:

Я понимаю, что этому вопросу почти два года, но он помог мне найти фактический ответ на исходный вопрос, чего на самом деле не дает ни один из приведенных выше ответов (ответы @ata и @l0b0). Вопрос был «Как мне передать массив в функцию bash?», В то время как @ata был близок к тому, чтобы сделать это правильно, его метод не дает реального массива для использования в самой функции. Требуется одно незначительное дополнение.

Итак, предполагая, что у нас было anArray=(a b c d) где-то перед вызовом функции do_something_with_array() , вот как мы определили бы функцию:

 function do_something_with_array {
    local tmp=$1[@]
    local arrArg=(${!tmp})

    echo ${#arrArg[*]}
    echo ${arrArg[3]}
}
  

Теперь

 do_something_with_array anArray
  

Правильно ли выводить:

 4
d
  

Если существует вероятность, что некоторые элементы вашего массива могут содержать пробелы, вам следует установить IFS значение, отличное от ПРОБЕЛА, а затем вернуть его обратно после того, как вы скопировали аргументы массива функции в локальные массивы. Например, используя приведенный выше:

 local tmp=$1[@]
prevIFS=$IFS
IFS=,
local arrArg=(${!tmp})
IFS=$prevIFS
  

Ответ №3:

ar это не первый параметр для тестирования — это все параметры. Вам придется сделать это echo "$@" в вашей функции.

Комментарии:

1. Ну, это не то, что я изначально предполагал, но это сделало свое дело: test() { for var in «$ @»; выполнить echo «1 $ var 2» } ar=(a b c) test ${ar[@]}