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