Beaucoup de réponses utilisant eval
et echo
type de travail, mais casser sur diverses choses, telles que plusieurs lignes, tenter d'échapper aux méta-caractères du shell, s'échapper à l'intérieur du modèle non destiné à être développé par bash, etc.
J'ai eu le même problème et j'ai écrit cette fonction shell qui, pour autant que je sache, gère tout correctement. Cela ne supprimera toujours que les nouvelles lignes de fin du modèle, en raison des règles de substitution de commande de bash, mais je n'ai jamais trouvé que c'était un problème tant que tout le reste restait intact.
apply_shell_expansion() {
declare file="$1"
declare data=$(< "$file")
declare delimiter="__apply_shell_expansion_delimiter__"
declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
eval "$command"
}
Par exemple, vous pouvez l'utiliser comme ceci avec un parameters.cfg
qui est vraiment un script shell qui définit simplement des variables, et un template.txt
qui est un modèle qui utilise ces variables :
. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt
En pratique, je l'utilise comme une sorte de système de modèle léger.
Je suis tombé sur ce que je pense être LA réponse à cette question :le envsubst
commande :
echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt
Cela affiche :hello 42 world
Si vous souhaitez continuer à travailler sur les données d'un fichier destination.txt
, repoussez ceci dans un fichier comme celui-ci :
envsubst < source.txt > destination.txt
Si ce n'est pas déjà disponible dans votre distribution, c'est dans le paquet GNU gettext
.
@Rockallite
- J'ai écrit un petit script wrapper pour résoudre le problème de '$'.
(BTW, il existe une "fonctionnalité" d'envsubst, expliquée sur https://unix.stackexchange.com/a/294400/7088 pour ne développer que certaines des variables de l'entrée, mais je suis d'accord qu'échapper aux exceptions est beaucoup plus pratique.)
Voici mon script :
#! /bin/bash
## -*-Shell-Script-*-
CmdName=${0##*/}
Usage="usage: $CmdName runs envsubst, but allows '\$' to keep variables from
being expanded.
With option -sl '\$' keeps the back-slash.
Default is to replace '\$' with '$'
"
if [[ $1 = -h ]] ;then echo -e >&2 "$Usage" ; exit 1 ;fi
if [[ $1 = -sl ]] ;then sl='\' ; shift ;fi
sed 's/\\\$/\${EnVsUbDolR}/g' | EnVsUbDolR=$sl\$ envsubst "[email protected]"