我已经成功地将单个数组作为参数调用,但是我无法通过多个数组。以下是我到目前为止的情况:
calling function {
array1=(1, 2, 3, 4)
array2=(a, b, c, d)
array3=(!, @, #, $)
called function() "${array1[@]" "${array2[@]}" "${array3[@]}"
}
called function {
local_array1=("${@}") # i am guessing my problem lies here?
local_array2=("${@}")
local_array3=("${@}")
echo ${local_array1[@]}
echo ${local_array2[@]}
echo ${local_array3[@]}
}
答案 0 :(得分:4)
函数或程序的参数列表是单个长数组。当你将三个不同的源数组连接到它上面时,结果仍然只是一个参数列表,这三个数组的内容是一个接一个的。
有两种解决方案。最安全的是连接到单个参数列表并按值传递参数,每个数组的前缀都是其长度:
caller() {
array1=(1 2 3 4)
array2=(a b c d)
array3=('!' '@' '#' '$')
callee \
"${#array1[@]}" "${array1[@]}" \
"${#array2[@]}" "${array2[@]}" \
"${#array3[@]}" "${array3[@]}"
}
callee() {
# using declare -a makes the values truly local
# without local or declare they're actually global
declare -a local_array1=( "${@:1:$1}" ); shift "$(( $1 + 1 ))"
declare -a local_array2=( "${@:1:$1}" ); shift "$(( $1 + 1 ))"
declare -a local_array3=( "${@:1:$1}" ); shift "$(( $1 + 1 ))"
printf 'array1 entry: %q\n' "${local_array1[@]}"
printf 'array2 entry: %q\n' "${local_array2[@]}"
printf 'array3 entry: %q\n' "${local_array3[@]}"
}
另一种方法是通过引用传递。如果你有bash 4.3,你可以使用名为namevars的新shell功能,首先由ksh为此明确实现:
caller() {
array1=(1 2 3 4)
array2=(a b c d)
array3=('!' '@' '#' '$')
callee array1 array2 array3
}
callee() {
declare -n local_array1=$1
declare -n local_array2=$2
declare -n local_array3=$3
printf 'array1 entry: %q\n' "${local_array1[@]}"
printf 'array2 entry: %q\n' "${local_array2[@]}"
printf 'array3 entry: %q\n' "${local_array3[@]}"
}
然而,pass-by-reference更脆弱:它取决于可变访问范围是否可以在任何相关位置访问,并且被调用者可以修改调用者中数组的值(实际上,当使用bash-4.3 namevar方法显示在这里时,该行为是自动的:对local_array1
的任何更改也会修改array1
)。
答案 1 :(得分:1)
第三个数组中的字符具有特殊含义,在bash中,可以传递两个第一个数组&像这样打印:
#!/bin/bash
called_function()
{
local local_array1=$1[@] # i am guessing my problem lies here?
local local_array2=$2[@]
echo ${!local_array1}
echo ${!local_array2}
}
calling_function()
{
array1=(1, 2, 3, 4)
array2=(a, b, c, d)
called_function array1 array2 #array3
}
calling_function
产生了这个:
./test.sh
1, 2, 3, 4
a, b, c, d