[bash] How to check if an environment variable exists and get its value?

I am writing a shell script. In this shell script, I am have a variable that either takes a default value, or the value of an environment variable. However, the environment variable doesn't have to be present.

For instance, assume, before running the script, I perform the following operation:

export DEPLOY_ENV=dev

How do I tell the script to search for this environment variable, and store its value in a variable inside the script. Moreover, how do I tell the script that if this environment variable does not exist, store a default variable?

This question is related to bash shell

The answer is


[ -z "${DEPLOY_ENV}" ] checks whether DEPLOY_ENV has length equal to zero. So you could run:

if [[ -z "${DEPLOY_ENV}" ]]; then
  MY_SCRIPT_VARIABLE="Some default value because DEPLOY_ENV is undefined"
else
  MY_SCRIPT_VARIABLE="${DEPLOY_ENV}"
fi

# or using a short-hand version

[[ -z "${DEPLOY_ENV}" ]] && MyVar='default' || MyVar="${DEPLOY_ENV}"

# or even shorter use

MyVar="${DEPLOY_ENV:-default_value}"

All the answers worked. However, I had to add the variables that I needed to get to the sudoers files as follows:

sudo visudo
Defaults env_keep += "<var1>, <var2>, ..., <varn>"

NEW_VAR=""
if [[ ${ENV_VAR} && ${ENV_VAR-x} ]]; then
  NEW_VAR=${ENV_VAR}
else
  NEW_VAR="new value"
fi

There is no difference between environment variables and variables in a script. Environment variables are just defined earlier, outside the script, before the script is called. From the script's point of view, a variable is a variable.

You can check if a variable is defined:

if [ -z "$a" ]
then
    echo "not defined"
else 
    echo "defined"
fi

and then set a default value for undefined variables or do something else.

The -z checks for a zero-length (i.e. empty) string. See man bash and look for the CONDITIONAL EXPRESSIONS section.

You can also use set -u at the beginning of your script to make it fail once it encounters an undefined variable, if you want to avoid having an undefined variable breaking things in creative ways.


You could just use parameter expansion:

${parameter:-word}

If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

So try this:

var=${DEPLOY_ENV:-default_value}

There's also the ${parameter-word} form, which substitutes the default value only when parameter is unset (but not when it's null).

To demonstrate the difference between the two:

$ unset DEPLOY_ENV
$ echo "'${DEPLOY_ENV:-default_value}' '${DEPLOY_ENV-default_value}'"
'default_value' 'default_value'
$ DEPLOY_ENV=
$ echo "'${DEPLOY_ENV:-default_value}' '${DEPLOY_ENV-default_value}'"
'default_value' ''

If you don't care about the difference between an unset variable or a variable with an empty value, you can use the default-value parameter expansion:

foo=${DEPLOY_ENV:-default}

If you do care about the difference, drop the colon

foo=${DEPLOY_ENV-default}

You can also use the -v operator to explicitly test if a parameter is set.

if [[ ! -v DEPLOY_ENV ]]; then
    echo "DEPLOY_ENV is not set"
elif [[ -z "$DEPLOY_ENV" ]]; then
    echo "DEPLOY_ENV is set to the empty string"
else
    echo "DEPLOY_ENV has the value: $DEPLOY_ENV"
fi