Creating Dynamic Variables in Bash
I've used this in the past to remove a bunch of if conditions when I had multiple sets of env variables for different environments.
Prefer video? Here it is on YouTube.
The approach we’re going to use is compatible with Bash 3.2+ which is nice if you want it to work out of the box on macOS.
#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset
# Imagine having a number of environment variables for a few enviroments such
# as TEST, STAGING and PROD. Typically these would exist in an .env file and
# are sourced with `. .env`, I left them here so it's self contained.
export TEST_API_KEY="abc123"
export STAGING_API_KEY="def456"
export PROD_API_KEY="ghi789"
# Now imagine you have a shell script where the first argument is the env you
# want to work with, such as `./demo TEST ...` or `./demo PROD ...`.
ENV="${1}"
# And now you want to use the value for a specific environment's API_KEY
# variable. At this point it doesn't matter which environment is came from.
API_KEY="${ENV}_API_KEY"
# Here we can access both the variable name as well as its value. You may want
# to use either one depending on your use case but the value is more common.
echo "${API_KEY}=${!API_KEY}"
If you ran this script with ./demo TEST
you’d get back API_KEY=abc123
.
Using ${!API_KEY}
is called indirect expansion. It’s in the official docs
for
Bash.
Without using dynamic variables you can solve the same problem but you might be inclined to write code that looks like this:
if [ "${ENV}" == "TEST" ]; then
API_KEY="${TEST_API_KEY}"
elif [ "${ENV}" == "STAGING" ]; then
API_KEY="${STAGING_API_KEY}"
elif [ "${ENV}" == "PROD" ]; then
API_KEY="${PROD_API_KEY}"
else
echo "Invalid environment!" && exit 1
fi
Now if you echo "${API_KEY}"
you’d get back abc123
if ENV="TEST"
.
It’s not like the above code is horrible. You could make a case it’s more straight forward but it can quickly become less maintainable.
If you have a bunch of environment variables I think using dynamic variables is a cleaner solution, it reduces a fair bit of duplication to declare the same variable for each environment.
The above is only one use case of using dynamic variables.
The video below goes over running the script and checking out its results.
# Demo Video
Timestamps
- 0:41 – Boilerplate for the demo script
- 1:30 – Creating a new variable to reference a dynamic name
- 2:06 – Getting the value of the dynamic variable name
- 2:50 – This could have been solved with an if statement instead
What use case have you used dynamic variables for? Let us know!