加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash – 嵌套函数调用中的变量赋值意外地更改了调用者范围中的局

发布时间:2020-12-15 22:04:14 所属栏目:安全 来源:网络整理
导读:编者注: 也许以下内容取自OP自己的答案,更好地说明了令人惊讶的行为: f(){local b = 1; G; echo $b; }; g(){b = 2; }; f# – ‘2’ 即,g()能够修改f()的本地$b变量. 在Zsh和Bash中,如果我有以下函数f(){a = 1; G; echo $a;和以下函数g(){a = 2;当我运行f时
编者注:
也许以下内容取自OP自己的答案,更好地说明了令人惊讶的行为:
f(){local b = 1; G; echo $b; }; g(){b = 2; }; f# – > ‘2’
即,g()能够修改f()的本地$b变量.

在Zsh和Bash中,如果我有以下函数f(){a = 1; G; echo $a;和以下函数g(){a = 2;当我运行f时,我得到以下输出而不是预期的:

$f
2

无论如何要禁用从函数到函数的这个变量渗透?

我正在研究一个相当大而重要的bash / zsh脚本,它在各种函数中使用了大量的变量;许多这些功能依赖于更大的主功能,但是由于变量通过一些相当不幸和意外的行为而流失,并且错误已经成为最重要的,阻止我自信地进一步发展,因为我想首先解决这个奇怪的问题.

我甚至尝试过使用local来本地化变量,但效果仍然存在.

编辑:请注意,我的问题不是关于如何使用局部变量来防止变量渗透或关于局部变量如何工作,如何设置局部变量,如何为已经声明的局部变量分配新值,或者任何一个废话:它是关于如何防止变量渗入调用者/被调用函数的范围.

解决方法

使用local创建一个不从父作用域继承的变量.

有一些有用的东西需要补充.

如果声明的函数调用另一个函数,则将继承(并且可以修改)局部变量.因此,本地保护对范围内较高的同名变量的更改,但范围不低.因此,必须在每个级别使用本地声明,除非您实际上想要更改父范围中的值.这与大多数编程语言的作用相反,并且具有优势(快速和脏的数据共享),但却难以调试失败模式.

可以使用本地-x导出局部变量以使其可用于子进程(非常有用),或者在使用本地-r创建时只读取.

一个很好的技巧是你可以在创建时使用从父作用域继承的值初始化变量:

local -r VAR="$VAR"

如果像我一样,总是使用set -u来避免静默使用未初始化的变量,并且无法确定已经分配了变量,那么如果未在父作用域中定义,则可以使用此值将其初始化为空值:

local -r VAR="${VAR-}"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读