【问题标题】:What does the bash' builtin declare -n z do with the z parameter?bash' 内置声明 -n z 对 z 参数有什么作用?
【发布时间】:2021-08-07 12:46:42
【问题描述】:

我很想知道 bash' declare -n 选项在只给出一个参数时是如何工作的。

例如:

declare -n z
echo "${z}"  # ""          (empty string as expected)
z="somevalue"
echo "${z}"  # ""          (empty string)

declare -n z
echo "${z}"  # ""          (empty string)
z="somevalue"
echo "${z}"  # somevalue   (huwh? How come z is now assigned a value?)

为什么第二个declare 调用似乎取消了nameref 属性? 为什么第二个赋值操作似乎工作,而第一个却没有?

我正在使用 bash 版本5.0.17(1)-release

【问题讨论】:

  • 你读过例如unix.stackexchange.com/q/510220?这不是特定于编程的。
  • @jonrshape 感谢您的节制。我之前确实看过该链接,但是-我的错-我只阅读了没有回答该问题的已接受答案。因此,我认为添加指向有用答案的链接对于文档目的很有价值:unix.stackexchange.com/a/510342/391074
  • @jonrshape。我已将问题更新为更具体,其他 StackExchange 问题未涵盖。我希望它对社区更有用。
  • 我认为这很好;这是一个关于bash 脚本语言语义的问题。

标签: bash built-in declare


【解决方案1】:

TL;DR:第一个赋值修复了z 引用的变量。第二个赋值改变了该变量的值。对declare 的第二次调用本质上是空操作;你已经在z 上设置了nameref 属性;第二次这样做没有任何改变。


第一次使用declare 时,z 未初始化且未定义。对z第一个 赋值(无论是在对declare 的调用中还是在它之后)决定了z 引用的是哪个变量。

$ declare -n z
$ echo $z

$ z=somevalue
$ declare -p z
declare -n z=somevalue

此时echo $z 不会产生任何值,因为somevalue 本身是未定义的。

您的 second 调用声明并没有真正对 z 做任何事情:

$ declare -n z
$ declare -p z
declare -n z=somevalue

它仍然是对变量somevalue 的引用。但是现在你对z 的第二次赋值做了一些不同的事情:它为变量somevalue 赋值,所以现在当你做echo $z 时,你会看到变量somevalue 的值,就像你有写echo $somevalue

如果我们对两个赋值使用不同的值,这会少一些混乱,所以我们可以区分引用的变量和它的值。

$ declare -n z
$ z=foo
$ declare -p z
declare -n z=foo
$ z=9
$ echo $foo
9

【讨论】:

  • 很好的解释,因为您准确地展示了如何使用declare -p 来调查正在发生的事情。我希望我的赞成票能出现。不幸的是,我的声誉还不够高。谢谢@chepner
  • 我联系了 Chet Ramey - GNU bash 和 GNU Readline 的维护者 - 他确认了您的回答。
猜你喜欢
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
相关资源
最近更新 更多