使用非标准名称取消设置 bash 函数变量

Posted

技术标签:

【中文标题】使用非标准名称取消设置 bash 函数变量【英文标题】:unset bash function variable with non-standard name 【发布时间】:2017-04-10 07:44:29 【问题描述】:

我可能在一个 bash 脚本中拥有这个函数,该脚本获取到 shell 的源代码

function suman
     echo "using suman function"

如果我打电话

unset suman

事情似乎按预期工作

但是,如果我有这个作为我的功能:

function suman-inspect 
     echo "using suman-inspect function"

如果我打电话

unset suman-inspect

unset "suman-inspect"

我收到这条消息:

bash: unset: `suman-inspect': not a valid identifier

如何按原样取消设置此变量?

【问题讨论】:

【参考方案1】:

Bash 允许在不处于 posix 模式时创建名称不是有效标识符的函数。

所以:

set -o posix
function suman-inspect  echo "using suman-inspect function"; 

给予:

bash: `suman-inspect': not a valid identifier

ruakh 通过引用man bash 提出了一个有效的观点。源代码 (builtins/set.def) 有注释:Posix.2 说先尝试变量,然后是函数,但是...

POSIX standard 表示 如果既没有指定 -f 也没有指定 -v,name 指的是一个变量;如果该名称的变量不存在,则未指定是否应取消设置该名称的函数(如果有)。

所以实际上行为是旧的备用“未指定*。如果有的话,错误在 bash 文档中。但公平地说,在 man bash 的其他地方它说:

可以使用 unset 内置函数的 -f 选项删除函数定义。

【讨论】:

【参考方案2】:

经过更多研究,似乎

unset -f "suman-inspect"

会起作用。这令人惊讶,因为unset suman 确实有效,并且确实成功地取消了 suman 函数的设置(据我所知)。

【讨论】:

+1 太棒了! unset 的文档说“如果没有提供选项,则每个 name 引用一个变量;如果没有该名称的变量,则未设置任何具有该名称的函数。”我假设即使变量不是有效的变量名,这也会起作用,但显然不是! 可能发生的情况是unset 假定它的参数(sans -f)是一个标识符,但如果不存在该名称的变量,请检查是否你的意思是取消设置一个功能。只有当您明确使用-f 时,bash 才会放宽“参数必须是有效标识符”规则。相当多的bash 扩展缺少对其语义的准确记录描述;其他一些示例包括进程替换(例如,>(...) 从哪里继承其标准 输出?)和函数导出(参见 ShellShock)。 suman-inspect 中的连字符/破折号是否使其成为无效标识符?

以上是关于使用非标准名称取消设置 bash 函数变量的主要内容,如果未能解决你的问题,请参考以下文章

如何取消设置鱼壳中的变量?

PHP函数中使用的变量会在函数执行后自动取消设置吗?

努力在 bash 中取消设置环境变量

为啥当我在函数中声明一个名称为全局数组的局部数组时,bash 会引发未绑定变量警告?

“header()” php 函数是不是取消设置全局变量?

使用与 C++ 标准允许的成员变量相同的名称为构造函数参数初始化成员变量? [复制]