script - shell linux definition




Forcer bash à développer des variables dans une chaîne chargée depuis un fichier (6)

  1. méthode bash , (variante d'une ligne de la réponse de Michael Neale ), en utilisant la substitution de processus et de commande :

    FOO=42 . <(echo -e echo $(<something.txt))
    

    Sortie:

    hello 42 world
    

    Notez que l' export n'est pas nécessaire.

  2. Méthode GNU sed evaluate , si something.txt comporte plusieurs lignes:

    FOO=42 sed 's/"/\\\"/g;s/.*/echo "&"/e' something.txt
    

J'essaye de trouver comment faire bash (force?) Développer des variables dans une chaîne (qui a été chargée à partir d'un fichier).

J'ai un fichier appelé "something.txt" avec le contenu:

hello $FOO world

Je cours ensuite

export FOO=42
echo $(cat something.txt)

cela renvoie:

   hello $FOO world

Il n'a pas augmenté $ FOO même si la variable a été définie. Je ne peux pas eval ou source le fichier - car il essayera et l'exécutera (ce n'est pas exécutable comme il est - je veux juste la chaîne avec les variables interpolées).

Des idées?


Beaucoup de réponses utilisent eval et echo type de travail, mais se brisent sur diverses choses, telles que plusieurs lignes, en essayant d'échapper des méta-caractères de shell, des échappements à l'intérieur du template non destinés à être développés par bash, etc.

J'ai eu le même problème, et a écrit cette fonction shell, qui, autant que je peux dire, gère tout correctement. Cela ne supprimera toujours que les retours à la ligne à la fin du modèle, à cause des règles de substitution de commandes de bash, mais je n'ai jamais trouvé que cela soit un problème tant que tout le reste reste 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 en fait un script shell qui ne fait que définir des variables, et un template.txt qui est un template 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 gabarit léger.


Les travaux suivants: bash -c "echo \"$(cat something.txt)"\"


Si vous voulez seulement que les références de variables soient développées (un objectif que j'ai eu pour moi-même), vous pouvez faire ce qui suit.

contents="$(cat something.txt)"
echo $(eval echo \"$contents\")

(Les citations échappées autour de $ contenu est la clé ici)


Une autre approche (qui semble bizarre, mais je la mets ici de toute façon):

Écrivez le contenu de something.txt dans un fichier temporaire, avec une instruction echo qui l'entoure:

something=$(cat something.txt)

echo "echo \"" > temp.out
echo "$something" >> temp.out
echo "\"" >> temp.out

puis revenez dans une variable:

RESULT=$(source temp.out)

et le résultat $ aura tout élargi. Mais cela semble tellement faux!


Vous ne voulez pas imprimer chaque ligne, vous voulez l' évaluer pour que Bash puisse effectuer des substitutions variables.

FOO=42
while read; do
    eval echo "$REPLY"
done < something.txt

Voir l' help eval ou le manuel de Bash pour plus d'informations.







unix