jjno91
jjno91

Reputation: 653

set default values for bash variables only if they were not previously declared

Here's my current process:

var[product]=messaging_app
var[component]=sms
var[version]=1.0.7
var[yum_location]=$product/$component/$deliverable_name
var[deliverable_name]=$product-$component-$version

# iterate on associative array indices
for default_var in "${!var[@]}" ; do

  # skip variables that have been previously declared
  if [[ -z ${!default_var} ]] ; then

    # export each index as a variable, setting value to the value for that index in the array
    export "$default_var=${var[$default_var]}"
  fi
done

The core functionality I'm looking for is to set a list of default variables that will not overwrite previously declared variables.

The above code does that, but it also created the issue of these variables can now not depend on one another. This is because the ordering of the associative array's indices output from "${!var[@]}" is not always the same as the order they were declared in.

Does a simpler solution exist like:

declare --nooverwrite this=that

I haven't been able to find anything akin to that.

Also, I'm aware that this can be done with an if statement. However using a bunch of if statements would kill the readability on a script with near 100 default variables.

Upvotes: 1

Views: 584

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80931

From 3.5.3 Shell Parameter Expansion:

${parameter:=word}

If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.

So

: ${this:=that}

: needed because otherwise the shell would see ${this:=that} as a request to run, as a command, whatever that expanded to.

$ echo "$this"
$ : ${this:=that}
$ echo "$this"
that
$ this=foo
$ echo "$this"
foo
$ : ${this:=that}
$ echo "$this"
foo

You can also to this the first place you use the variable (instead of on its own) if that suits things better (but make sure that's clear because it is easy to mess that up in later edits).

$ echo "$this"
$ echo "${this:=that}"
that
$ echo "$this"
that

Doing this dynamically, however, is less easy and may require eval.

Upvotes: 1

Related Questions