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).