Matt Matt - 9 days ago 5
Linux Question

Bash Script Properties File Using '.' in Variable Name

I'm new to bash scripting and have a question about using properties from a .properties file within a bash script.

I have seen a bash properties file that uses'.' between variable names, for example:

this.prop.one=someProperty


and I've seen them called from within a script like:

echo ${this.prop.one}


But when I try to set this property I get an error:

./test.sh: line 5: ${this.prop.one}: bad substitution


I can use properties if I do it without '.' in the variable names, and include the props file:

#!/bin/bash
. test.properties
echo ${this_prop_one}


I would really like to be able to use '.' in the variable names, and, if at all possible, not have to include . test.properties in the script.

Is this possible?

UPDATE:

Thanks for your answers! Well, then this is strange. I'm working with a bash script that looks like this (a service for glassfish):

#!/bin/bash

start() {
sudo ${glassfish.home.dir}/bin/asadmin start-domain domain1
}

...


...and there are property files like this (build.properties):

# glassfish
glassfish.version=2.1
glassfish.home.dir=${app.install.dir}/${glassfish.target}
...


So, there must be some way of doing this right? Are these maybe not considered 'variables' by definition if they're declared in a properties file? Thanks again.

Answer

Load them into an associative array. This will require your shell to be bash 4.x, not /bin/sh (which, even when a symlink to bash, runs in POSIX compatibility mode).

declare -A props
while read -r; do
  [[ $REPLY = *=* ]] || continue
  props[${REPLY%%=*}]=${REPLY#*=}
done <input-file.properties

...after which you can access them like so:

echo "${props[this.prop.name]}"

If you want to recursively look up references, then it gets a bit more interesting.

getProp__property_re='[$][{]([[:alnum:].]+)[}]'
getProp() {
  declare -A seen=( ) # to prevent endless recursion
  declare propName=$1
  declare value=${props[$propName]}
  while [[ $value =~ $getProp__property_re ]]; do
    nestedProp=${BASH_REMATCH[1]}
    if [[ ${seen[$nestedProp]} ]]; then
      echo "ERROR: Recursive definition encountered looking up $propName" >&2
      return 1
    fi
    value=${value//${BASH_REMATCH[0]}/${props[$nestedProp]}}
  done
  printf '%s\n' "$value"
}

If we have props defined as follows:

declare -A props=( [glassfish.home.dir]='${app.install.dir}/${glassfish.target}' [app.install.dir]=/install [glassfish.target]=target )

...then behavior is as follows:

bash4-4.4$ getProp glassfish.home.dir
${app.install.dir}/${glassfish.target}