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

Как передать массив в качестве аргумента функции в Bash

Как мы знаем, в bash-программировании способ передачи аргументов составляет $1 ,..., $N Однако я обнаружил, что нелегко передать массив в качестве аргумента функции, которая получает более одного аргумента. Вот один пример:

f(){
 x=($1)
 y=$2

 for i in "${x[@]}"
 do
  echo $i
 done
 ....
}

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "${a[@]}" $b
f "${a[*]}" $b

Как описано, функция f получает два аргумента: первый присваивается x который является массивом, второй - y.

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

jfaldsj 
jflajds

Второй способ использует "${a[*]}" в качестве первого аргумента, и результат:

jfaldsj 
jflajds 
LAST

Ни один из результатов не соответствует желаемому. Итак, есть ли у кого-нибудь идеи о том, как правильно передавать массив между функциями?

4b9b3361

Ответ 1

Вы не можете передать массив, вы можете передавать только его элементы (т.е. расширенный массив).

#! /bin/bash
function f() {
    a=("[email protected]")
    ((last_idx=${#a[@]} - 1))
    b=${a[last_idx]}
    unset a[last_idx]

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f "${x[@]}" "$b"
echo ===============
f "${x[*]}" "$b"

Другая возможность - передать массив по имени:

#! /bin/bash
function f() {
    name=$1[@]
    b=$2
    a=("${!name}")

    for i in "${a[@]}" ; do
        echo "$i"
    done
    echo "b: $b"
}

x=("one two" "LAST")
b='even more'

f x "$b"

Ответ 2

Вы можете передать массив по ссылке на функцию в bash 4.3+. Это происходит, вероятно, из ksh, но с другим синтаксисом. Основная идея - установить атрибут -n:

show_value () # array index
{
    local -n array=$1
    local idx=$2
    echo "${array[$idx]}"
}

Это работает для индексированных массивов:

$ shadock=(ga bu zo meu)
$ show_value shadock 2
zo

Он также работает для ассоциативных массивов:

$ days=([monday]=eggs [tuesday]=bread [sunday]=jam)
$ show_value days sunday
jam

См. также declare -n на странице руководства.

Ответ 3

Сначала вы можете передать "скалярное" значение. Это упростит ситуацию:

f(){
  b=$1
  shift
  a=("[email protected]")

  for i in "${a[@]}"
  do
    echo $i
  done
  ....
}

a=("jfaldsj jflajds" "LAST")
b=NOEFLDJF

f "$b" "${a[@]}"

В этот момент вы можете также использовать позиционные параметры array-ish непосредственно

f(){
  b=$1
  shift

  for i in "[email protected]"   # or simply "for i; do"
  do
    echo $i
  done
  ....
}

f "$b" "${a[@]}"

Ответ 4

Это решит проблему передачи массива в функцию:

#!/bin/bash

foo() {
    string=$1
    array=([email protected])
    echo "array is ${array[@]}"
    echo "array is ${array[1]}"
    return
}
array=( one two three )
foo ${array[@]}
colors=( red green blue )
foo ${colors[@]}