为什么这个函数在我传入关联数组时只看到两个值,而在传入普通数组时却看到三个值?

编程语言 2026-07-10
  • 这是我的函数
#!/usr/bin/env bash

function run_aws_ssm_delete_parameters() {
    local -r enable_logging="$1"
    local -n parameter_names="$2"
    shift 2

    local -a aws_cli_flags=(
        "delete-parameters"
        "--names"
        "${parameter_names[@]}"
    )

    aws_cli_flags+=("$@")

    set -x
    if result="$(aws ssm "${aws_cli_flags[@]}")"; then
        set +x
        [[ "${enable_logging}" = true ]] && printf "Good: %s\n" "${result}"
        return 0
    else
        set +x
        printf "Bad: %s" "$?"
        return 1
    fi
}

function main() {
    local -a normal_array=("one" "two" "three")
    run_aws_ssm_delete_parameters true normal_array --color on

    local -A associative_array=(
        ["one"]="value_one"
        ["two"]="value_two"
        ["three"]="value_three"
    )

    run_aws_ssm_delete_parameters true "${!associative_array[@]}" --color on
}

main "$@"
  • 我在运行时得到的输出。我会修复凭据问题,但重点放在传递给数组名称的参数上
++ aws ssm delete-parameters --names one two three --color on

Unable to locate credentials. You can configure credentials by running "aws configure".
+ result=
+ set +x
Bad: 0++ aws ssm delete-parameters --names three one --color on

Unable to locate credentials. You can configure credentials by running "aws configure".
+ result=
+ set +x
Bad: 0%
  • 那么让我们尝试对普通数组做同样的事情,只传递关联数组的名称
  • 让我修改主函数
function main() {
    local -a normal_array=("one" "two" "three")
    run_aws_ssm_delete_parameters true normal_array --color on

    local -A associative_array=(
        ["one"]="value_one"
        ["two"]="value_two"
        ["three"]="value_three"
    )

    run_aws_ssm_delete_parameters true associative_array --color on
}

main "$@"
  • 现在让我们看看输出
++ aws ssm delete-parameters --names one two three --color on

Unable to locate credentials. You can configure credentials by running "aws configure".
+ result=
+ set +x
Bad: 0++ aws ssm delete-parameters --names value_two value_three value_one --color on

Unable to locate credentials. You can configure credentials by running "aws configure".
+ result=
+ set +x
Bad: 0%
  • 现在它发送了值,我在这里怎么发送键名?
  • 如需了解,正在Apple M1最新系统的zsh终端上运行

解决方案

注: 主题具有误导性;你是在把苹果(发送普通数组的名称)与橙子(发送关联数组的索引)进行比较

解释当前的行为...

这个命令需要数组的 名称

local -n parameter_names="$2"

第一次调用函数时你应该看到 $2 == normal_array,其中 normal_array 是数组的有效名称。

第二次调用函数时你应该看到 $2 == two,但 two 不是一个有效的数组名,因此 parameter_names 最终被设为一个空数组;这意味着 "${parameter_names[@]}" 不会产生任何输出。其余的 "${!associative_array[@]}"threeone)被作为“正常”的输入参数处理,成为 aws_cli_flags 数组的一部分。

如果你添加以下内容,可以看到这一行为:

aws_cli_flags+=("$@")

typeset -p parameter_names ${!parameter_names} aws_cli_flags    # new code

set -x

在你的代码中再增加一个 typeset -p 调用时,应该生成:

declare -n parameter_names="normal_array"
declare -a normal_array=([0]="one" [1]="two" [2]="three")
declare -a aws_cli_flags=([0]="delete-parameters" [1]="--names" [2]="one"

... snip ...

declare -n parameter_names="two"
bash: typeset: two: not found
declare -a aws_cli_flags=([0]="delete-parameters" [1]="--names" [2]="three" [3]="one" [4]="--color" [5]="on")

作为参数传递数组名(associative_array)时的输出:

declare -n parameter_names="associative_array"
declare -A associative_array=([two]="value_two" [three]="value_three" [one]="value_one" )
declare -a aws_cli_flags=([0]="delete-parameters" [1]="--names" [2]="value_two" [3]="value_three" [4]="value_one" [5]="--color" [6]="on")

至于你要做的(发送数组的索引) ...

你需要根据你想要发生的结果来调整方法。

如果你仍然想把 数组名 发送给函数,那么 在函数内 你可以用以下方式引用该(局部)数组的索引:

${!parameter_names[@]}

typeset -p ... 调用之后添加以下内容以演示:

echo "parameter_names indices : ${!parameter_names[@]} :"

这应该生成如下输出行(对应上述片段):

#####
# function called with 'normal_array'

parameter_names indices : 0 1 2 :

#####
# function called with '"${!associative_array[@]}"'
# NOTE: 'two' is an invalid array name so parameters_names[] is empty, hence no indices

parameter_names indices :  :

#####
# function called with 'associative_array'

parameter_names indices : two three one :

你需要决定函数是处理数组的索引还是数组的值,并据此编写代码。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章