Shell脚本中函数内无法获取数组值的问题排查
问题原因分析与解决方案
我来帮你拆解这个问题——核心原因是Bash中declare -a在函数内会创建局部变量,而普通变量默认是全局的,这导致数组在prerequisite函数退出后就被销毁了,而普通变量能保留下来。
先还原你的代码与现象
run.sh 代码:
#This is run.sh prerequisite(){ config_file=./../config/config.sh source $config_file echo "VAR1 inside prerequisite: $VAR1" echo "country currency inside prerequisite: ${country_currency[@]}" } LIST_OF_COUNTRIES=`cat country_list.txt` transform() { local country="$@" prerequisite echo "VAR1 inside transform: $VAR1" echo "country currency inside transform: ${country_currency[@]}" } transform ${LIST_OF_COUNTRIES[@]} & transformpid=$! wait $transformpid echo "Complete"
config.sh 代码:
VAR1="value1" declare -a country_currency=( "INR" "USD" "JPY" )
运行输出:
VAR1 inside prerequisite: value1 country currency inside prerequisite: INR USD JPY VAR1 inside transform: value1 country currency inside transform:
为什么会这样?
Bash有个容易踩坑的规则:
- 普通变量(比如
VAR1="value1")如果没有用declare/local修饰,默认是全局变量,哪怕在函数内定义(或source进来),函数退出后依然有效。 - 但用
declare -a(或declare -i等)定义变量时,如果是在函数内部执行(比如你在prerequisite里source包含declare -a的config.sh),declare会默认把这个变量变成当前函数的局部变量——也就是说,country_currency只在prerequisite函数内部有效,函数执行完就被销毁了,所以transform里拿不到它。
解决办法(三种可选)
方法1:修改config.sh,把数组声明为全局变量
在declare后加-g选项(Bash 4.2+支持),强制让数组成为全局变量:
VAR1="value1" declare -ga country_currency=( "INR" "USD" "JPY" )
这样不管在哪里source这个文件,数组都会是全局的,transform里就能正常获取。
方法2:在prerequisite函数里,把数组导出到全局
如果不能修改config.sh,可以在prerequisite函数source完后,手动把数组赋值给全局变量:
prerequisite(){ config_file=./../config/config.sh source $config_file # 把局部数组赋值给全局同名变量 country_currency=( "${country_currency[@]}" ) echo "VAR1 inside prerequisite: $VAR1" echo "country currency inside prerequisite: ${country_currency[@]}" }
原理是:虽然source进来的数组是局部的,但我们可以把它的内容复制到全局的country_currency变量中(默认不存在的话赋值后就是全局的)。
方法3:避免在函数内用declare定义数组
如果你的Bash版本比较旧,或者不想用-g,可以直接去掉config.sh里的declare -a,数组依然能正常使用:
VAR1="value1" country_currency=( "INR" "USD" "JPY" )
Bash中直接赋值的数组默认是全局的,除非用local或declare(不带-g)修饰。
验证效果
不管用哪种方法,运行脚本后transform里的country_currency都会正常输出INR USD JPY,和VAR1一样能被获取到。
内容的提问来源于stack exchange,提问作者Djeah
相关产品推荐
相关产品推荐

