【问题标题】:Assigning to a variable in a parent context in Bash在 Bash 中分配给父上下文中的变量
【发布时间】:2020-08-20 11:37:09
【问题描述】:

我想写一个类似于read 内置函数,我将变量名作为参数传递,函数将其结果返回到命名的变量中。

我试过这样做:

GLOBAL_VAR=0

foo() {
    local var="$1"; shift
    local result

    # ...

    (( GLOBAL_VAR++ ))

    # ...

    eval "${var}=\${result}"
}

但是上面有一个问题:如果我用第一个参数varresult 调用foo,上面的方法就不起作用,因为这样赋值就变成了在@987654329 中定义的局部变量@ 而不是它的调用者。实际上,这泄露了foo 的实现。

如果我改用 nameref (local -n),则运行 foo var 会产生警告消息,而 foo result 不会向调用者返回任何内容,因为在函数中分配了 result 变量。而且我不能只是将变量重命名为不会冲突的东西,因为我实际上打算在这里执行递归,因此变量将不可避免地与自身发生冲突。 Namerefs 根本无法解决我的问题。

我也不能使用子shell,因为那样对全局变量的任何修改都会丢失。

有没有一种方法可以分配给在调用者上下文中定义的动态命名变量

(换句话说,我正在寻找与 Tcl 的 upvar 等效的 bash。)

【问题讨论】:

  • 这能回答你的问题吗? Passing arguments by reference
  • 在函数中,declare 使变量成为本地变量,所以我不能使用它。链接的答案对这个问题的问题没有帮助:使用它会导致environment: warning: var: circular name reference
  • declare makes variables local 在没有特定参数的情况下使用,是的。为什么这有关系? environment: warning: var: circular name reference 并且该问题没有可能的解决方案。所以declare -n _pIcK_uNiQuE_NaMe_FoR_nAmE_rEfErEnCe="$1"
  • @user3840170:您尚未回复上述评论。为什么函数中引用变量的名称很重要?
  • 相关:Circular name references in bash shell function, but not in ksh。我认为 Bash 5 应该可以解决这个问题,但就像 Kusalananda 的回答一样,它确实做得不好。

标签: bash variables scope dynamic-scope upvar


【解决方案1】:

我怀疑你最终会得到类似的东西:

foo() {
    local result
    result="some computation with $1"
    echo "$result"
}

thing=$(set -eu; foo)

【讨论】:

  • 我特意说了不想用subshel​​l。
猜你喜欢
  • 2020-08-12
  • 1970-01-01
  • 2016-07-14
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
相关资源
最近更新 更多