我试图理解以下unset
部分https://unix.stackexchange.com/a/381782/674
unset
在bash
仅取消设置已在当前作用域中声明的变量(尽管在全局范围内除外,但仍保留其声明;它删除了属性和值,变量不再是数组或散列;另请注意,在 namerefs 上,它会取消设置引用的变量)。否则,它只是从上面提到的堆栈中弹出一个变量层。
Bash手册没有提到任何相关的内容,或者我错过了。
你能用例子解释一下吗
- “仅取消设置已在当前作用域中声明的变量”
“尽管在全球范围内除外,但仍声明这一点”。
如果
unset
变量位于函数的局部作用域中,那么该unset
变量不仅未设置而且未声明吗?如果
unset
变量位于全局范围内,该unset
变量是否只是未设置但仍已声明?如何检查变量是否已声明?
“否则,它只会从上面提到的堆栈中弹出一个变量层。”
“否则”和“一个变量层”是什么意思?
谢谢。
答案1
最好举例说明:
$ bash -c 'a=0; f() { local -i a=1; unset a; typeset -p a; a=2; }; f; echo "$a"'
declare -- a
0
这是unset
在同一范围内声明的变量上调用的。它已正确未设置。它仍然被声明(尽管它已经丢失了属性和值),但它仍然限于该范围。您会看到,即使我们执行了 a a=2
,但仍然是在a
本地 to上完成的f
,来自外部范围的不受影响。这很好,也是我们想要的。
在:
$ ./bash -c 'a=0; f() { local a=1; g; a=2; }; g() { unset a; echo "$a"; }; f; echo "$a"'
0
2
可以看到并unset a
没有取消设置a
。相反,它揭示了下面的那个,来自外部范围的那个。当g
返回时,f
的a
变量将不再是局部的。
在 bash 5+ 中,可以通过设置选项来解决这个问题localvar_unset
。
请注意,情况更糟的是哪里mksh
?yash
unset
爆裂代替取消设置即使对于已在同一范围内声明的变量也是如此。他们的第一个例子给出:
typeset a=0
2
进一步阅读: