Using Nested Default Variable Values in a Shell Script
We'll cover a use case that lets us set a value through a flag, environment variable or fall back to using your working directory.
I’m always a fan of exploring ideas through a practical use case.
For example with Docker Compose you can set your project name in 3 different ways:
docker compose --project-name hello ...
flagCOMPOSE_PROJECT_NAME=hello
environment variable- Default to using the current directory’s name
This post doesn’t have anything to do with Docker Compose but the above is a nice example of a tool optimizing for developer experience.
Personally I almost always set the COMPOSE_PROJECT_NAME
environment variable
since you typically use an .env
file with Docker projects and it can be
defined there. This allows you to define your project name in code and have it
be consistent across environments.
But with that said, it’s nice to have it work out of the box with no config and
give you an option to override the environment variable with the flag if you’re
testing something or maybe aren’t using an .env
file.
In this post we’re going to wire up a shell script to support the same feature.
Here’s the whole script:
#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset
project_name="${1:-${PROJECT_NAME:-$(basename "${PWD}")}}"
echo "${project_name}"
All we did was expand on the idea of setting a single default value for a
variable such as ${1:-hello}
. The only difference is a variable is the
default value and we can repeat that as many times as needed.
If you find the above too hard to read you can always replace the 1 liner with:
project_name=
if [ -n "${1:-}" ]; then
project_name="${1}"
elif [ -n "${PROJECT_NAME:-}" ]; then
project_name="${PROJECT_NAME}"
else
project_name="$(basename "${PWD}")"
fi
Both versions of the code output the same thing:
$ ./demo hello
hello
$ PROJECT_NAME=cool ./demo
cool
$ PROJECT_NAME=cool ./demo hello
hello
# In this case, I'm in ~/src/tutorials/arg-values
$ ./demo
arg-values
The video below demos the above script.
# Demo Video
Timestamps
- 0:14 – Docker Compose does this nicely
- 2:09 – Setting up a basic shell script
- 3:27 – A dynamic default value
- 4:08 – Getting the basename of the current directory
- 4:54 – Unraveling our 1 liner into an if else condition
Do you often use this pattern? Let me know below.