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