Как передать массив в качестве аргумента функции в 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
Ни один из результатов не соответствует желаемому. Итак, есть ли у кого-нибудь идеи о том, как правильно передавать массив между функциями?
Ответы
Ответ 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[@]}