Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Using Nested Default Variable Values in a Shell Script

using-nested-default-variable-values-in-a-shell-script.jpg

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.

Quick Jump:

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 ... flag
  • COMPOSE_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.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments