GNU/Linux >> Tutoriels Linux >  >> Linux

Forcer bash à développer des variables dans une chaîne chargée à partir d'un fichier

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]"

Linux
  1. Utilisation d'une référence à une variable de chaîne Bash dans Sed ?

  2. Lecture de lignes à partir d'un fichier avec Bash :pour Vs. Tandis que?

  3. Comment supprimer les retours à la ligne d'un fichier texte ?

  4. Remplacement des variables d'environnement dans un fichier de propriétés

  5. Bash :ajouter une chaîne à la fin du fichier sans saut de ligne

Remplacement de chaîne dans Bash

Dans Bash, comment ajouter une chaîne après chaque ligne dans un fichier ?

Ouvrir Vim depuis un script shell Bash

Rediriger toutes les sorties vers un fichier à l'aide de Bash sous Linux ?

Script bash pour supprimer le fichier le plus ancien d'un dossier

bash + lire les variables et les valeurs du fichier par le script bash