在bash中传递多个数组作为参数
问题描述:
我已经成功地将单个数组作为参数调用,但是我在通过多个数组时遇到了问题。以下是我迄今为止:在bash中传递多个数组作为参数
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[@]}
}
答
性状第三阵列中具有特殊的意义,在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
答
函数或程序的参数列表是单个长阵列。当将三个不同的源数组连接到它上时,结果仍然只有一个参数列表,并且这三个数组的内容依次排列。
有两种解决方案。最安全的一个是连接到一个单一的参数列表,并通过值传递参数,通过其长度前缀每个阵列:
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,你可以使用一个新的shell功能,称为namevars,首先由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[@]}"
}
然而,通过按引用是略逊一筹:这取决于变量范围是可以随处访问,并且被调用者可以修改调用者中数组的值(实际上,当使用此处显示的bash-4.3 namevar方法时,该行为是自动的:对local_array1
的任何更改也将修改array1
)。
传递参考?绝对聪明,但读者应该意识到这与典型的按价值方法之间的语义差异。 –