在 bash 中传递多个数组作为参数

2024-04-29

我已经成功地能够调用单个数组作为参数,但在传递多个数组时遇到问题。这是我到目前为止所拥有的:

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[@]}
}

函数或程序的参数列表是单个长数组。当您将三个不同的源数组连接到其上时,结果仍然只是one参数列表,依次包含这三个数组的内容。

有两种解决方案。最安全的方法是连接到单个参数列表并按值传递参数,每个数组以其长度为前缀:

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[@]}"
}

然而,按引用传递有点脆弱:它依赖于变量作用域可以在任何相关的地方访问,并且被调用者可以修改调用者中数组的值(事实上,当使用此处显示的 bash-4.3 namevar 方法时,该行为是自动的:任何更改local_array1也会修改array1).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 bash 中传递多个数组作为参数 的相关文章

随机推荐