包含从 bash 中的函数加载的数组的配置文件

Config file with array loaded from function in bash

我有以下 bash 文件用作配置:

# config
servers=(
    [vagrant.host]=192.168.20.20
    [vagrant.port]=22
    [vagrant.user]=ubuntu
    [vagrant.identity]=~/.ssh/id_rsa
    [vagrant.cwd]=/home/ubuntu/website
)

然后我使用以下方法从我的主脚本加载它:

declare -A servers
. config

echo "${servers["vagrant.host"]}" # prints 192.168.20.20

如果代码不在函数中,效果很好,但我不需要始终加载配置文件,我将加载代码放在函数中。当我调用如下所示的函数时,我收到一个错误。

function loadConfig {
    declare -A servers
    . config
}

loadConfig

echo "${servers["vagrant.host"]}" 
# vagrant.host: syntax error: invalid arithmetic operator (error token is ".host")

我不知道是什么导致了错误,Google 没有帮助。

关联数组默认是 local 作用域,通过添加 -g 标志使其成为全局

declare -Ag servers

The declare builtin command

-g create global variables when used in a shell function; otherwise ignored (by default, declare declares local scope variables when used in shell functions)

运行 与调试器模式下的明显脚本相同的脚本,让我产生了这个,

$ bash -x mainscript.sh
+ loadConfig
+ declare -Ag servers
+ . config
++ servers=([vagrant.host]=192.168.20.20 [vagrant.port]=22 [vagrant.user]=ubuntu [vagrant.identity]=~/.ssh/id_rsa [vagrant.cwd]=/home/ubuntu/website)
+ echo 192.168.20.20
192.168.20.20

使用 declare -g 简单明了。

但是也会造成全局变量的污染。在这种情况下,您想使用 config 而不想使用全局变量,您可以在函数调用中定义变量,例如:

function loadConfig {
    declare -n main=""    # needs bash 4.3 - create an reference to indirect name
    declare -A servers      # the array name used in the config (local only)
    . ./conf
    # copy the array to indrectly aliased array...
    for key in "${!servers[@]}"
    do
        main["$key"]="${servers["$key"]}"
    done
}

#MAIN
declare -A currservers  #declare your current array
loadConfig currservers  #pass its name to loadConfig

echo "${currservers['vagrant.host']}"
# 192.168.20.20

不幸的是,这需要合理的新 bash 版本 4.3+