为什么这个函数在我传入关联数组时只看到两个值,而在传入普通数组时却看到三个值?
- 这是我的函数
#!/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[@]}"(three 和 one)被作为“正常”的输入参数处理,成为 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。