我一直在使用间接扩展,并依赖于变量未设置时结果为空字符串:
$ $SHELL --version | head -1
GNU bash, version 4.4.23(1)-release (x86_64-unknown-linux-gnu)
$ unset var
$ echo "${!var}"
$
但在一个新的 Linux 机器上失败了invalid indirect expansion
:
$ $SHELL --version | head -1
GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu)
$ unset var
$ echo "${!var}"
-bash: var: invalid indirect expansion
$
显然,我可以更改我的代码以在两个地方工作,但到目前为止,我还无法找出导致 1 失败但另一个失败的 2 个系统之间的确切差异,我想知道这种差异是最好的解决这个问题以及将来出现的任何类似问题。
如果只是 bash 版本的更改,我找不到任何发行说明或任何表明这一点的内容。如果在其中设置了某个选项,我也找不到(例如不是set -u
)。 FWIW 这是shopt
发生故障的机器(第二列)和未发生故障的机器(第三列)之间的输出差异:
$ awk 'FNR==1{ARGIND++} {a[$1,ARGIND]=$2; b[$1]} END{for (var in b) if (a[var,1] != a[var,2]) print var, a[var,1], a[var,2]}' bad good | column -t
autocd off
compat32 off
localvar_unset off
lastpipe off
localvar_inherit off
complete_fullquote on
assoc_expand_once off
checkwinsize on off
globasciiranges on
compat40 off
compat41 off
compat42 off
inherit_errexit off
compat43 off
compat44 off
checkjobs off
expand_aliases on off
globstar off
progcomp_alias off
dirspell off
direxpand off
login_shell on off
有人确切地知道为什么我在一个 Unix 机器上看到故障,而在另一个 Unix 机器上却没有看到故障吗?
答案1
5.0-alpha 有所改变,CHANGES
Bash 源中的文件有这个条目:
This document details the changes between this version, bash-5.0-alpha, and
the previous version, bash-4.4-release.
[...]
y. If indirect expansion attempts to indirectly reference through an unset
variable, report an error.
以下是邮件列表中作者关于此问题的帖子:https://lists.gnu.org/archive/html/bug-bash/2016-11/msg00165.html
很明显,尝试通过未设置的变量或值为空的变量进行引用的间接扩展应该是一个错误。 Bash-4.3 没有最好的错误检查,而 bash-4.4 捕获空值情况。我也会修复它以捕获未设置的变量情况。
事实上,在 Bash 4.4 中,存在空值错误的情况:
$ ./bash4.4 -c 'var=; echo ${!var}'
./bash4.4: : bad substitution