1

I'm working on a bash script that supposed to read a config file and use it later. The config file looks like this:

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

I found this question helpful while figuring out how to parse the file: Bash Parse Arrays From Config File

The relevant code from the answer is this:

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

This code works great when I use it as a pure script. However, if I wrap it with a function, the script terminates after reading the first key (I used set -o xtrace to find this out).

Why this code:

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

The output looks like this:

++ 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)

Causes an error(Command terminated), while the first, pure-script, isn't?

(The title is far from perfect, I not sure how to describe it more accurately.)

Thanks!

Dima.Go
  • 472
  • 2
  • 7
  • 17
  • both the cases work fine, can't seem to reproduce your error. What `bash` version do you have installed? Can you post the full error seen? – Inian Jun 11 '18 at 07:59
  • I edited the question with the error, the version is: GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu) – Dima.Go Jun 11 '18 at 08:07
  • Must be a pretty old Bash. 4.4.12 does not core on `declare 'config[local]=127.0.0.1'`. – ceving Jun 11 '18 at 08:13
  • On my machine, in the 'pure' version it doesn't, in the function id does. I can't figure out what's the difference. – Dima.Go Jun 11 '18 at 08:15
  • 1
    Maybe a Bash bug. – ceving Jun 11 '18 at 08:22

1 Answers1

0

As Inian said both version run without syntax error. But the second has a logical error, because the Bash manual page says:

When used in a function, declare and typeset make each name local, as with the local command, unless the -g option is supplied

This means, your config data is only available in your function. And when the function terminates, the config gets garbage collected.

ceving
  • 21,900
  • 13
  • 104
  • 178
  • I don't even get to the phase where I try to access the config object - the script terminates after reading the first key-value pair – Dima.Go Jun 11 '18 at 08:12