GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash zwingen, Variablen in einem aus einer Datei geladenen String zu erweitern

Viele der Antworten mit eval und echo Art von Arbeit, aber bricht bei verschiedenen Dingen ab, wie z. B. mehreren Zeilen, dem Versuch, Shell-Metazeichen zu maskieren, Escapes innerhalb des Templates, das nicht dazu bestimmt ist, durch Bash erweitert zu werden, usw.

Ich hatte das gleiche Problem und schrieb diese Shell-Funktion, die, soweit ich das beurteilen kann, alles korrekt verarbeitet. Dies wird aufgrund der Befehlsersetzungsregeln von Bash immer noch nur abschließende Zeilenumbrüche aus der Vorlage entfernen, aber ich habe nie festgestellt, dass dies ein Problem darstellt, solange alles andere intakt bleibt.

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

Sie können es zum Beispiel so mit einem parameters.cfg verwenden das ist wirklich ein Shell-Skript, das nur Variablen setzt, und ein template.txt Das ist eine Vorlage, die diese Variablen verwendet:

. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt

In der Praxis verwende ich dies als eine Art leichtgewichtiges Vorlagensystem.


Ich bin über die meiner Meinung nach DIE Antwort auf diese Frage gestolpert:die envsubst Befehl:

echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt

Dies gibt aus:hello 42 world

Wenn Sie die Daten in einer Datei weiter bearbeiten möchten destination.txt , schieben Sie dies zurück in eine Datei wie diese:

envsubst < source.txt > destination.txt

Falls es noch nicht in Ihrer Distribution verfügbar ist, ist es im GNU-Paket gettext enthalten .

@Rockallite

  • Ich habe ein kleines Wrapper-Skript geschrieben, um das '$'-Problem zu lösen.

(Übrigens gibt es ein "Feature" von envsubst, das unter https://unix.stackexchange.com/a/294400/7088 erklärt wird, um nur einige der Variablen in der Eingabe zu erweitern, aber ich stimme zu, dass es viel bequemer ist, die Ausnahmen zu umgehen.)

Hier ist mein Skript:

#! /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. Verwenden einer Referenz auf eine Bash-String-Variable in Sed?

  2. Leerzeichen für Variablen in Bash-Skript?

  3. Lesen von Zeilen aus einer Datei mit Bash:Für Vs. Während?

  4. Wie füge ich in Bash nach jeder Zeile in einer Datei eine Zeichenfolge hinzu?

  5. Öffnen Sie Vim aus einem Bash-Shell-Skript heraus

Ersetzen von Zeichenfolgen in Bash

Wie entferne ich Zeilenumbrüche aus einer Textdatei?

Ersetzen von Umgebungsvariablen in einer Eigenschaftendatei

Alle Ausgaben mit Bash unter Linux in eine Datei umleiten?

Auflisten von Zeilen aus nur einer Datei in DIFF

Entfernt eine bestimmte Zeile aus der Bash-Verlaufsdatei