bash 非数组 ${!name[@]} 参数扩展困惑

标签 bash shell

鉴于 Bash Reference Manual3.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[@]:-default}${!name [@]:+alt} 当内容改变 ${!name[@]} 扩展本身如何扩展时扩展?

最佳答案

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

有趣的问题是,“[@] 在该表达式中修改了什么?”它似乎在修改 f,当 f 是一个标量时它什么都不做,但当 f 是一个以上的数组时它会产生一个无效的名称元素;在这种情况下,似乎会发生默认值替换。

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

关于bash 非数组 ${!name[@]} 参数扩展困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27807615/

相关文章:

java - 典型的预构建 Nagios 插件(例如 check_load)的源代码是什么?

linux - 从 txt 文件 unix 中选择错误的列值

windows - Windows 7 x64 的 shell 扩展 dll 中未调用 InvokeCommand

python - 在 Windows 上的 Emacs 中运行 Python

regex - 使用 grep 或 sed 的正则表达式不起作用

bash - 通过 Bash shell WSL1 安装 Yarn

linux - 使用 tee 命令打印垃圾字符

bash - nginx在docker上的配置问题-对没有实例的docker进行故障排除

linux - 如何找到没有。 bash 字符串中某个字符出现的次数?

bash - 在 "vagrant ssh"时自动 chdir 到 vagrant 目录