gpt4 book ai didi

bash - 使 nameref 成为 bash 中的常规变量

转载 作者:行者123 更新时间:2023-11-29 09:12:40 25 4
gpt4 key购买 nike

编辑:这已被确认为错误并将被修复:https://lists.gnu.org/archive/html/bug-bash/2018-03/msg00055.html


所以我在摆弄 bash 的间接功能 namerefs。我以为我已经掌握了窍门,但当我试图弄清楚如何将 nameref 变成常规变量时,我突然遇到了一些让我困惑的事情。

这是来自 man bash 的相关段落:

declare -n Give each name the nameref attribute, making it a name reference to another variable. That other variable is defined by the value of name. All references, assignments, and attribute modifications to name, except those using or changing the -n attribute itself, are performed on the variable referenced by name's value.


我理解的部分

假设您想取消设置一个名称引用——不是它指向的变量,而是变量本身。你不能只说 unset foo,因为这实际上会取消设置 foo 指向的任何内容;相反,您必须将其设为常规变量,然后取消设置:

$ declare -p

$ foo=bar; bar='hello world'

$ declare -p
declare -- foo="bar"
declare -- bar="hello world"

$ declare -n foo; declare -p # 'foo' is now a nameref
declare -n foo="bar"
declare -- bar="hello world"

$ declare +n foo; declare -p # 'foo' is no longer a nameref
declare -- foo="bar"
declare -- bar="hello world"

$ unset foo; declare -p # 'foo' is unset, not bar
declare -- bar="hello world"

我不明白的地方

这一切对我来说都是有意义的,并且与我对上述手册段落的阅读是一致的。令我困惑的是上面的一个小变化会发生什么——也就是说,我们保留 bar 未设置和未声明:

...
$ declare -p
declare -n foo="bar"

$ echo "${foo}" # These two commands behave as expected--i.e., identically to how namerefs usually behave, just with an unset variable.
-bash: foo: unbound variable

$ echo "${!foo}"
bar

$ declare +n foo; declare -p # Should make 'foo' a regular variable, right? Nope.
declare -n foo="bar" # Still a nameref--wtf?
declare -- bar # And now bar's back--unset still, but declared. Wtf??

$ declare +n foo; declare -p # THIS, however, works like I thought it would--but *why*? In both cases 'bar' is unset...
declare -- foo="bar"
declare -- bar

我显然误解了 nameref 应该如何工作。根据 man 的文章,我认为取消设置 foo 的 nameref 属性应该适用于 foo,无论它的目标是 bar , 未声明。

请注意,当 bar 未设置但已声明时,它的工作方式与我想象的一样。这对我来说是最奇怪的部分——我没有意识到未声明的变量有任何意义! test -v${var-_}${var+_}set -u所有似乎都只关心变量是否设置,并且不区分 (A) 未设置、未声明的变量和 (B) 未设置、已声明的变量。

有人可以解释一下这里发生了什么,也许可以指出手册中对此进行解释的部分吗?在 namerefs 的行为中是否还有其他特殊情况会让我感到困惑?谢谢!


可能相关的信息:

$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-unknown-linux-gnu)
...

$ echo "$-"
himuBCHs

请注意,在没有 set -u 的情况下,该行为仍然存在;我这样做只是为了使 bash 的消息更清晰一些。

最佳答案

unset 有一个新参数,明确用于取消定义 nameref(与它指向的变量相反):

unset -n namevar

关于bash - 使 nameref 成为 bash 中的常规变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49179596/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com