我今天读了这篇文章
“Local只能在函数中使用;它使变量名称具有 可见范围仅限于该职能及其子女。“ ABS指南作者认为这种行为是一个错误。
我想出了这个脚本
begin () {
local foo
alpha
}
alpha () {
foo=333 bar=444
bravo
}
bravo () {
printf 'foo %3s bar %s\n' "$foo" "$bar"
}
begin
bravo
输出
foo 333 bar 444
foo bar 444
所以你可以看到,因为我没有local bar
,它泄露到了全球
范围。问题:
set -a
标记的方式
出口的一切?答案 0 :(得分:3)
一个局部变量是否可用于子函数实际上是一个bug,还是仅仅是他的意见?
不,这不是一个错误。这只是他的意见。
Bash是否有办法将所有内容标记为本地,类似于set -a标记出口的所有内容?
没有
如果不这样做,Bash是否有办法检查这些泄露的全局变量?
是。试试"设置"或"声明",两者都没有任何参数。
答案 1 :(得分:1)
如果不这样做,Bash是否有办法检查这些泄露的全局变量?
没有。 Bash有一个名为“隐藏变量”的无证概念,这使得无法测试是否设置了本地而不会干扰变量。
此测试演示隐藏变量以及unset内置函数的范围敏感性。
function f {
case $1 in 1)
typeset x=1
f 2
;;
2)
typeset x
unset -v x # Does nothing (demonstrates hidden local)
f 3
;;
[345])
printf "x is %sunset\n" ${x+"not "}
unset -v x
f $(($1 + 1))
esac
}
f 1
# output:
# x is unset
# x is not unset
# x is unset
Bash有办法强制使用declare -g
设置全局,但是没有办法强制bash取消引用它,或测试它是否已设置,使得该功能的实用性非常有限。
这有希望清楚地说明问题
f() {
local x="in x" # Assign a local
declare -g x=global # Assign a global
declare -p x # prints "in x"
unset -v x # try unsetting the local
declare -p x # error (x is invisible)
}
f
declare -p x # x is visible again, but there's no way to test for that before now.