Home > Enterprise >  How could I combine "default assignment" and conversion to lowercase?
How could I combine "default assignment" and conversion to lowercase?

Time:06-30

I would like to combine default assignment, as seen here, with conversion to lowercase, as seen here.

This is what I'm working with:

bash-3.2$ export MY_ENV_VAR=FaLsE
bash-3.2$ : "${MY_ENV_VAR:=false}"
bash-3.2$ echo $MY_ENV_VAR
FaLsE

I would like to set the value of MY_ENV_VAR to lowercase in a single statement since I have 20 lines of code grabbing values of environment variables and I'd rather not add 20 additional lines to do the conversion by itself.

I've tried a few things, like:

bash-3.2$ : "${MY_ENV_VAR:=false,,}"
bash-3.2$ echo $MY_ENV_VAR
FaLsE

That method seems like it would work if I had Bash 4 but I'm on 3.2.

I've also tried:

bash-3.2$ myval=$(: "${MY_ENV_VAR:=false}" | tr '[:upper:]' '[:lower:]')
bash-3.2$ echo $myval

bash-3.2$

And:

bash-3.2$ myval=$(: echo "${MY_ENV_VAR:=false}" | tr '[:upper:]' '[:lower:]')
bash-3.2$ echo $myval

bash-3.2$

Which I didn't expect to work but I don't understand the default assignment enough to know how that would be used to feed the conversion to lowercase. I find certain features of Bash difficult to understand.

CodePudding user response:

Since you are using Bash, use built-in case modification:

#!/bin/bash

export MY_ENV_VAR=
for MY_ENV_VAR in FaLsE '' tRuE
do
  # Expands to lower-case
  MY_ENV_VAR=${MY_ENV_VAR,,}

  # Assigns default value
  MY_EN_VAR=${MY_ENV_VAR:=false}

  # Prints it to see
  printf 'MY_ENV_VAR=%s\n' "$MY_ENV_VAR"
done

Actual output is as expected:

MY_ENV_VAR=false
MY_ENV_VAR=false
MY_ENV_VAR=true

Now, rather than repeating this 20 times for every variable, then make it into a function:

exportLowerDefault() {
  local -- v=${!1}
  v=${v,,}
  v=${v:=$2}
  export "$1"="$v"
}

for MY_ENV_VAR in FaLsE '' tRuE
do
  exportLowerDefault MY_ENV_VAR false

  # Prints it to see
  printf 'MY_ENV_VAR=%s\n' "$MY_ENV_VAR"
done

CodePudding user response:

Unfortunately, you cannot use nested substitution in bash (and most other shells).

However, in your specific case you can use tools such a tr to handle the lowercase conversion, and use variable substitution to handle the default value.

For instance :

MY_ENV_VAR=$(tr [:upper:] [:lower:] <<< ${MY_ENV_VAR:=false})

Another (uglier) solution would be to use a subshell :

MY_ENV_VAR=$(TMP=${MY_ENV_VAR,,}; echo "${TMP:=false}")

CodePudding user response:

A function is an entity for encompassing a sequence of repeated tasks.

set_default_value_and_conver_to_lowercase() {
   declare -n _var=$1
   : "${_var:-$2}"
   _var=${_var,,}
}

set_default_value_and_conver_to_lowercase MY_ENV_VAR false

For that old bash3, you could use eval instead of namereference, hopefully with some error checking:

set_default_value_and_conver_to_lowercase() {
   local _var
   if ! <<<"$1" grep -qx '[A-Z_]*'; then exit 1; fi
   eval "_var=\${$1}"
   : "${_var:-$2}"
   _var=${_var,,}
   printf -v "$1" "%s" "$_var"
}

set_default_value_and_conver_to_lowercase MY_ENV_VAR false

CodePudding user response:

This seems to work for me -

MY_ENV_VAR=$(tr [:upper:] [:lower:] <<< $MY_ENV_VAR)
echo $MY_ENV_VAR
# false
  • Related