我面临一个非常奇怪的问题。我知道我错过了一些基本的东西,但对于我的生活,我无法弄清楚是什么。
在文件tmp.sh
中考虑这些声明:
declare -A aa
aa[1]=hello
aa[2]=world
myfunc() {
echo exists
}
myvar=exists
我将脚本作为source tmp.sh
来源并运行:
myfunc
echo $myvar
echo ${aa[@]}
输出结果为:
exists
exists
hello world
现在我做同样的事情,但把源语句放在一个函数中:
mysource() {
filename="$1"
source "$filename"
}
这次输出是:
exists
exists
这里发生了什么?
答案 0 :(得分:2)
将-g
选项添加到declare
。 [1]
来自手册
-g在shell函数中使用时创建全局变量;否则忽略(默认情况下,声明在shell函数中使用时声明局部作用域变量)
从chepner的评论中提及
也很有用source的工作原理是执行文件的内容,就像将source命令替换为文件内容一样。即使声明语句不在文件中的函数中,它们也是调用source的函数的一部分。
[1] -g
选项需要Bash 4.2 or above。
答案 1 :(得分:0)
默认情况下,declare
在函数中使用时会创建本地变量(换句话说:在函数内部{{1}默认情况下,行为与declare
)相同。
从函数内部创建全局变量:
Bash local
:
4.2+
(例如declare -g
)较早的Bash版本,包括declare -g foo='bar'
:
3.x
),不要使用foo='bar'
。暂且不说:
您的示例代码使用declare
来声明关联数组,这需要Bash declare -A
。
关联数组是唯一类型的(非环境)变量,它们严格需要 4.0
语句来创建它们 - 你不能创建没有declare
的关联数组,而你可以通过简单的赋值隐式地创建(非整数类型的)标量和数组。
因此,鉴于declare -A
需要Bash declare -g
,如果您碰巧遇到4.2
或4.0
,则无法解决您的问题。
4.1
版本的Bash不会遇到此问题,因为他们并不完全支持3.x
。