564

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?

4
  • 12
    printenv DEPLOY_ENV should do it Commented Sep 2, 2016 at 15:57
  • I tried, for testing purposes tempV=$(printenv LANG) it did not print anything, despite the system having the value of LANG Commented Sep 2, 2016 at 15:58
  • 1
    Your statement doesn't "print" anything. It stores the value of the environment variable LANG into the shell variable tempV. As for the other suggestions in this thread: Note that with none of them, you can distinguish, whether you have an environment variable or a shell variable. If this distinction is really important, the solution suggested by @sjsam should be considered. Commented Sep 3, 2016 at 6:17
  • Most compact way is : ${MY_VARIABLE:?} It will print a message and return with non-0 code if it doesn't exist: -bash: MY_VARIABLE: parameter null or not set. See also null command Commented May 10, 2024 at 9:00

5 Answers 5

908

[ -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}"
Sign up to request clarification or add additional context in comments.

11 Comments

You can replace "${DEPLOY_ENV}" with $DEPLOY_ENV
MyVar="$DEPLOY_ENV:-default_value" didn't work for me though on bash, so it's generally safer to surround with curly braces ${...} where possible.
This works and may have value in edge cases, but it's a re-invented wheel... Instead, see the parameter "expansion answer", which was made for this exact goal.
@Finesse Always quote a tested string. tldp.org/LDP/abs/html/comparison-ops.html
This will error if you use set -euo pipefail. You need to use @Eugene method of default values first before the -z test MyVar=${DEPLOY_ENV:-}
|
208

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' ''

1 Comment

My script was not able to read the value of DEPLOY_ENV, In order to be sure that the environment variable exists in the system, I wrote printenv DEPLOY_ENV in the terminal, and the correct value was returned. However, the script was not able to fetch it.
136

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

15 Comments

Note that the -v option was introduced in Bash 4.2, and many systems are still running older versions of Bash.
Even bash 4.2 is over 5 years old at this point; I tend to treat anything older as a special case that deserves special mention in the question.
the list of reasons to switch to linux gets another entry... thanks @chepner
You can install a new version yourself.
@DmitryShevkoplyas -v has worked for arrays (both indexed and associative) since bash 4.2. The special parameters are either always set, or indeed handled differently. (For example, test the value of $# to see which positional parameters are actually set.)
|
68

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.

3 Comments

"There is no difference between environment variables and variables in a script." -- to clarify: this is not true in the important sense that, while an environment variable is also a shell variable, a shell variable is not always exported as an environment variable. Here are some ways to tell if a variable is exported: superuser.com/questions/450868/…
Not true. If you set env variable to an empty string this still returns "not defined".
This answer is incorrect as @j4r3k identified. The -z checks if the environment variable is either not set or set to an empty string. If you really want to distinguish between being set or not being set use if [ -z "${a+1}" ] as described by Gilles' answer to unix.stackexchange.com/questions/654566/…
7
NEW_VAR=""
if [[ ${ENV_VAR} && ${ENV_VAR-x} ]]; then
  NEW_VAR=${ENV_VAR}
else
  NEW_VAR="new value"
fi

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.