将代码移动到bash函数会导致错误功能

时间:2018-06-11 07:51:42

标签: bash

我正在研究一个bash脚本,该脚本应该读取配置文件并在以后使用它。 配置文件如下所示:

[config]
key1=value1
key2=value2
key3=value3

我发现这个问题很有帮助,同时弄清楚如何解析文件:Bash Parse Arrays From Config File

答案中的相关代码是:

while read line; do 
if [[ $line =~ ^"["(.+)"]"$ ]]; then 
    arrname=${BASH_REMATCH[1]}
    declare -A $arrname
elif [[ $line =~ ^([_[:alpha:]][_[:alnum:]]*)"="(.*) ]]; then 
    declare ${arrname}[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
fi
done < config.conf

当我将它用作纯脚本时,此代码非常有用。但是,如果我用函数包装它,脚本会在读完第一个键后终止(我使用set -o xtrace来查找它)。

为什么这段代码:

read_config() {
    while read line; do 
    if [[ $line =~ ^"["(.+)"]"$ ]]; then 
        arrname=${BASH_REMATCH[1]}
        declare -A $arrname
    elif [[ $line =~ ^([_[:alpha:]][_[:alnum:]]*)"="(.*) ]]; then 
        declare ${arrname}[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
    fi
  done < $1
}
read_config config.conf

输出如下:

++ read_config
++ read line
++ [[ [config] =~ ^\[(.+)]$ ]]
++ arrname=config
++ declare -A config
++ read line
++ [[ local=127.0.0.1 =~ ^\[(.+)]$ ]]
++ [[ local=127.0.0.1 =~ ^([_[:alpha:]][_[:alnum:]]*)=(.*) ]]
++ declare 'config[local]=127.0.0.1'
Segmentation fault (core dumped)

导致错误(命令终止),而第一个纯脚本不是?

(标题远非完美,我不确定如何更准确地描述它。)

谢谢!

1 个答案:

答案 0 :(得分:0)

因为Inian说两个版本都没有语法错误。但第二个有逻辑错误,因为Bash手册页说:

  

在函数中使用时,declare和typeset使每个名称都是本地的,与local命令一样,除非提供了-g选项

这意味着,您的配置数据仅在您的功能中可用。当函数终止时,配置会被垃圾收集。