【发布时间】:2020-08-20 11:37:09
【问题描述】:
我想写一个类似于read 内置函数,我将变量名作为参数传递,函数将其结果返回到命名的变量中。
我试过这样做:
GLOBAL_VAR=0
foo() {
local var="$1"; shift
local result
# ...
(( GLOBAL_VAR++ ))
# ...
eval "${var}=\${result}"
}
但是上面有一个问题:如果我用第一个参数var 或result 调用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