鉴于Bash Reference Manual部分中的3.5.3 Shell Parameter Expansion
说:
${!name[@]} ${!name[*]}
如果name是数组变量,则展开到名称中指定的数组索引(键)列表。如果name不是数组,则在设置name时扩展为0,否则为null。当使用“@”并且扩展名出现在双引号内时,每个键都会扩展为单独的单词。
和
$ {参数:-word}
如果参数未设置或为null,则替换单词的扩展。否则,参数的值将被替换。
和
$ {参数:+字}
如果参数为null或未设置,则不替换任何内容,否则将替换word的扩展。
有人可以向我解释以下扩展的输出:
$ 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[@]:-default}
和${!name[@]:+alt}
扩展的扩展方式${!name[@]}
扩展本身如何扩展?
答案 0 :(得分:3)
在语法${!f[@]}
中,参数扩展被解析为“列出键”表达式,这是{!
引入间接级别的规则的特定例外之一。语法${!f[@]:-b}
与该模式不匹配(因为它以:-b
结尾),因此!
被解释为间接引用,因此它是 name 的值是f
的值,由默认值修饰符测试。
有趣的问题是,“[@]
在该表达式中修改了什么?”它似乎正在修改f
,当f
是标量时它不会执行任何操作,但当f
是包含多个元素的数组时会产生无效的名称;在这种情况下,似乎会发生默认值替换。
我最好的猜测是,这是一个未记录的,可能是非预期的参数扩展的角落。