Advanced dotenv config files for bash scripts
25 Apr 2021A technique commonly used practice in (deployment of) software projects is to put your local configuration, environment variables and secrets in a .env
file in the root of your project. This .env file is structured as a one-dimensional lookup table (a list of key=value
lines), and saved only on that server, never checked in to the project code.
Every programming/scripting language has at least 1 popular package dedicated to exactly this:
- github.com/vlucas/phpdotenv (PHP - 11K )
- github.com/theskumar/python-dotenv/ (Python - 4K )
- github.com/bkeepers/dotenv (Ruby - 6K )
- github.com/joho/godotenv (Golang - 4K )
- github.com/motdotla/dotenv/ (JS - 13K )
There is, however, no such package for bash. The reason is that the .env syntax can be executed by bash as-is, no need to write a package for this1.
For bashew (my bash scripting micro-framework), I have created a more evolved .env strategy, with multiple .env files (potentially) read when a script executes. It looks for 4 separate .env files in a fixed sequence and, if they exist, they are executed:
import_env_if_any() {
local env_files=("$script_install_folder/.env"
"$script_install_folder/$script_prefix.env"
"./.env"
"./$script_prefix.env")
local env_file
for env_file in "${env_files[@]}"; do
if [[ -f "$env_file" ]]; then
debug "$config_icon Read config from [$env_file]"
source "$env_file"
fi
done
}
How does this work? Let’s take splashmark as an example.
- the
$HOME/.basher/cellar/bin/splashmark/.env
2 contains the Unsplash and Pixabay API keys that the script needs to search for/download images - I have a symlink
sm_github
->splashmark.sh
and thesm_github.env
file contains all the settings specific for my GitHub images: width, height, font-size … - for certain projects like Every country in the world in 1 (Unsplash) photo I can create a .env file in the project’s image folder and save the settings for those images.
- I could have separate .env files for separate symlinked aliases.
I have found having this flexibility in every script I create makes life really easier.
-
Executing a .env file in bash has the advantage/danger that you can execute arbitrary code inside a .env file, which is great for things like
YEAR_NOW=$(date '+%Y')
↩ -
resolving the installation folder is explained in Find installation folder for bash scripts ↩