在bash中将多个数组作为参数传递 [英] passing multiple arrays as a parameter in bash

查看:126
本文介绍了在bash中将多个数组作为参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经能够成功调用单个数组作为参数,但是我无法通过多个数组.这是我到目前为止的内容:

I have successfully been able to call a single array as a parameter, but I am having trouble passing through multiple arrays. Here is what I have so far:

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

推荐答案

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

A function or program's argument list is a single, long array. When you concatenate three different source arrays onto it, the result is still only one argument list, with the contents of those three arrays one after the other.

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

There are two solutions. The safest one is to concatenate onto a single argument list and pass arguments by value, with each array prefixed by its length:

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明确实现:


The other approach is to pass by reference. If you have bash 4.3, you can use a new shell feature called namevars, first implemented by ksh explicitly for this purpose:

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

However, pass-by-reference is somewhat more fragile: It depends on variable scope being accessible everywhere relevant, and a callee can modify values of the arrays in the caller (indeed, when using the bash-4.3 namevar approach showing here, that behavior is automatic: Any change to local_array1 will also modify array1).

这篇关于在bash中将多个数组作为参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆