在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 
+0

传递参考?绝对聪明,但读者应该意识到这与典型的按价值方法之间的语义差异。 –

函数或程序的参数列表是单个长阵列。当将三个不同的源数组连接到它上时,结果仍然只有一个参数列表,并且这三个数组的内容依次排列。

有两种解决方案。最安全的一个是连接到一个单一的参数列表,并通过值传递参数,通过其长度前缀每个阵列:

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)。