edruder.com i write about anything, or nothing

Easy Property files for Bash scripts

Recently, I wanted to have a setting/preference to control an aspect of a Bash script. I considered using an environment variable, but I wanted the preference to be able to be different based on the directory that the script is run from—the “local” directory’s setting would override the “global” setting.

I’ve used a hierarchy of YAML files from Java—but YAML is overkill and I just needed two levels of hierarchy. A simple “properties file”, with settings in the local file overriding the settings in the global file in the home directory, works. A properties file is a text file, usually with a .properties extension, with one property per line, and each line looking like this: property=value.

Searching online, I found a simple sed command that nicely plucks specific properties from a file. With that, I wrote a simple Bash function that returns the value of a property from a properties file, looking first in the properties file in the directory where the script was invoked, then in the properties file in the home directory.

Here’s the function:

prop() {
  name=$1

  local_properties="$(pwd)"/"$properties_filename"
  if [[ -f "$local_properties" ]]; then
    value=$(sed -En "s/^$name=([^\n]+)$/\1/p" "$local_properties")
  fi

  if [[ -z "$value" ]]; then
    global_properties=~/"$properties_filename"
    if [[ -f "$global_properties" ]]; then
      value=$(sed -En "s/^$name=([^\n]+)$/\1/p" "$global_properties")
    fi
  fi

  echo "$value"
}

The function expects the variable properties_filename to be defined.

It’s invoked like this:

if [[ "$(prop 'allow_something')" == "true" ]]; then
  # do something
fi

Note:

  • This is on macOS, which has slightly different syntax for the sed options than is described in the original article (macOS: -En vs. Linux: -rn).
  • The function interprets an “empty” value as “no property is defined”, so you probably don’t want to define a property without a value (i.e., property=).
  • I usually make my preferences files invisible.
  • I usually don’t commit my preferences files to source control.