#!/bin/sh # ===================================================================================== # Safe .env reader for the host-side scripts. # # Do NOT `. ./.env`. A file that is perfectly valid for docker-compose is NOT valid shell: # AD_DNS_FORWARDER=1.1.1.1 8.8.8.8 # compose: fine. shell: runs "8.8.8.8"! # That exact thing silently broke a backup run. So we parse the file instead of executing it. # # Behaviour: # * KEY=VALUE, first '=' splits; the value keeps any later '=' (LDAP URIs, passwords) # * surrounding quotes are stripped; inline " # ..." is dropped on unquoted values # * full-line comments and blanks are ignored # * an existing environment variable WINS, so tests/CI can override: # AD_ADMIN_PASSWORD=x ./scripts/backup.sh # # Usage (bash/dash): . scripts/envfile.sh && ad_env_load .env # ===================================================================================== ad_env_load() { _f="${1:-.env}" [ -f "$_f" ] || return 0 while IFS='=' read -r _k _v || [ -n "$_k" ]; do case "$_k" in ''|[\ \#]*) continue ;; esac # key: strip whitespace/CR _k="$(printf '%s' "$_k" | tr -d '\r' | sed 's/[[:space:]]*$//')" case "$_k" in ''|\#*) continue ;; esac # value: trim, strip one layer of quotes, or drop an inline comment _v="${_v%$'\r'}" _v="${_v#"${_v%%[![:space:]]*}"}" case "$_v" in \"*\") _v="${_v#\"}"; _v="${_v%\"}" ;; \'*\') _v="${_v#\'}"; _v="${_v%\'}" ;; *) _v="${_v%%[[:space:]]#*}" ;; esac _v="${_v%"${_v##*[![:space:]]}"}" # rtrim # don't clobber a value already provided in the environment if [ -z "$(printenv "$_k" 2>/dev/null)" ]; then export "$_k=$_v" fi done < "$_f" unset _f _k _v }