← retour aux snippets

envsubst: templating simple sans sed

Remplacer des variables d'environnement dans un fichier modèle de façon sûre.

objectif

Templater des fichiers en substituant des variables d’environnement de manière sûre, sans bricoler avec sed -i.

code minimal

# substituer uniquement les variables whitelistees
export APP_NAME="demo" APP_PORT="8080"
envsubst '${APP_NAME} ${APP_PORT}' < config.tmpl > config.conf

utilisation

# 1) préparer un template simple (ex: config.tmpl)
cat > config.tmpl <<'EOF'
server {
  name = ${APP_NAME}
  port = ${APP_PORT}
}
EOF

# 2) définir les valeurs et sécuriser les permissions de sortie
umask 077
export APP_NAME="mon-app"
export APP_PORT="8080"

# 3) substitution contrôlée (whitelist)
envsubst '${APP_NAME} ${APP_PORT}' < config.tmpl > config.conf

# 4) vérification rapide
grep -E 'name|port' config.conf

variante(s) utile(s)

# fail-fast: vérifier que toutes les variables requises existent
need='APP_NAME APP_PORT'
for v in $need; do
  [ -n "${!v:-}" ] || { echo "variable manquante: $v" >&2; exit 1; }
done
envsubst '$(printf " \${%s}" $need)' < config.tmpl > config.conf

# substitution d'un fichier .env sans polluer l'environnement global
set -a
. ./app.env   # contient APP_NAME=..., APP_PORT=...
set +a
envsubst '${APP_NAME} ${APP_PORT}' < config.tmpl > config.conf

# templater un script shell sans exécuter le code
envsubst '${PATH} ${HOME}' < script.tmpl.sh > script.sh
chmod +x script.sh

# écriture atomique pour éviter les fichiers partiels
tmp="$(mktemp -p . .config.conf.XXXXXX)"
envsubst '${APP_NAME} ${APP_PORT}' < config.tmpl > "$tmp" && mv -f "$tmp" config.conf

notes

  • whitelistez les variables dans la ligne envsubst pour éviter de remplacer par erreur d’autres variables présentes.
  • umask 077 protège les fichiers générés contenant des secrets.
  • envsubst ne gère pas les opérateurs de défaut type ${VAR:-def}; définissez les valeurs avant l’appel.
  • pour des grands templates, validez la sortie avec une commande de lint adaptée (ex: nginx -t, jsonlint).