将多个数组作为参数传递给bash

时间:2016-01-20 16:40:55

标签: arrays 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[@]}
}

2 个答案:

答案 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