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

时间:2015-01-06 21:39:12

标签: bash shell

鉴于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[@]}扩展本身如何扩展?

1 个答案:

答案 0 :(得分:3)

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

有趣的问题是,“[@]在该表达式中修改了什么?”它似乎正在修改f,当f是标量时它不会执行任何操作,但当f是包含多个元素的数组时会产生无效的名称;在这种情况下,似乎会发生默认值替换。

我最好的猜测是,这是一个未记录的,可能是非预期的参数扩展的角落。