bash 非数组 ${!name[@]} 参数扩展混乱

bash non-array ${!name[@]} parameter expansion confusion

鉴于 Bash Reference Manual in section 3.5.3 Shell Parameter Expansion 说:

${!name[@]}
${!name[*]}

If name is an array variable, expands to the list of array indices (keys) assigned in name. If name is not an array, expands to 0 if name is set and null otherwise. When ‘@’ is used and the expansion appears within double quotes, each key expands to a separate word.

${parameter:-word}

If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

${parameter:+word}

If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

有人可以向我解释以下扩展的输出吗:

$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
$ cat hm.sh
p() {
    printf "%-11s : f=%1s : " "$*" "$f"
    eval printf \'%1s :\n\' "$@"
}

p '$f'
p '${!f[@]}'
p '${!f[@]:-b}'
echo "echo: ${!f[@]:-b} :"
p '${!f[@]:+b}'
echo "echo: ${!f[@]:+b} :"
f=f
p '$f'
p '${!f[@]}'
p '${!f[@]:-b}'
echo "echo: ${!f[@]:-b} :"
p '${!f[@]:+b}'
echo "echo: ${!f[@]:+b} :"
f=t
p '$f'
p '${!f[@]}'
p '${!f[@]:-b}'
echo "echo: ${!f[@]:-b} :"
p '${!f[@]:+b}'
echo "echo: ${!f[@]:+b} :"

$ bash hm.sh
$f          : f=  :   :
${!f[@]}    : f=  :   :
${!f[@]:-b} : f=  : b :
echo: b :
${!f[@]:+b} : f=  :   :
echo:  :
$f          : f=f : f :
${!f[@]}    : f=f : 0 :
${!f[@]:-b} : f=f : f :
echo: f :
${!f[@]:+b} : f=f : b :
echo: b :
$f          : f=t : t :
${!f[@]}    : f=t : 0 :
${!f[@]:-b} : f=t : b :
echo: b :
${!f[@]:+b} : f=t :   :
echo:  :

这就是为什么当内容 改变${!name[@]}扩展本身的扩展方式?

在语法 ${!f[@]} 中,参数扩展被解析为 "list the keys" 表达式,这是 {! 引入间接级别的规则的特定例外之一.语法 ${!f[@]:-b} 与该模式不匹配(因为它以 :-b 结尾),因此 ! 被解释为间接引用,因此它是 namef 的值的变量,它正在被默认值修饰符测试。

有趣的问题是,"what does the [@] modify in that expression?" 似乎在修改 f,当 f 是标量时它什么都不做,但当 f 是时产生无效名称一个以上元素的数组;在这种情况下,似乎会发生默认值替换。

我最好的猜测是,这是一个未记录且可能是无意的参数扩展极端情况。