Lösung 1:
Das ist sehr gut möglich. Eine sehr einfache Möglichkeit, dies zu implementieren, wäre, dass die Vorlagendatei tatsächlich das Skript ist und Shell-Variablen wie
verwendet#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
cat > /tmp/destfile <<-EOF
here is some config for version $version which should
also reference this path $path
EOF
Sie könnten dies sogar auf der Befehlszeile konfigurierbar machen, indem Sie version=$1
angeben und path=$2
, sodass Sie es wie bash script /foo/bar/baz 1.2.3
ausführen können . Die -
bevor EOF dazu führt, dass Leerzeichen vor den Zeilen ignoriert werden, verwenden Sie einfach <<EOF
wenn Sie dieses Verhalten nicht wünschen.
Eine andere Möglichkeit, dies zu tun, wäre die Verwendung der Such- und Ersetzungsfunktion von sed
#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
sed -e "s/VERSION/$version/g" -e "s/PATH/$path/" /path/to/templatefile > /tmp/destfile
was jede Instanz der Zeichenfolgen VERSION und PATH ersetzen würde. Wenn es andere Gründe gibt, warum diese Zeichenfolgen in der Vorlagendatei enthalten sind, können Sie Ihre Suche und Ersetzung auf VERSION setzen oder %VERSION% oder etwas, das weniger wahrscheinlich versehentlich ausgelöst wird.
Lösung 2:
Der einfachste Weg, dies einfach in der Linux-CLI zu tun, ist die Verwendung von envsubst
und Umgebungsvariablen.
Beispielvorlagendatei apache.tmpl
:
<VirtualHost *:${PORT}>
ServerName ${SERVER_NAME}
ServerAlias ${SERVER_ALIAS}
DocumentRoot "${DOCUMENT_ROOT}"
</VirtualHost>
Führen Sie envsubst
aus und Ergebnis in neue Datei my_apache_site.conf
ausgeben :
export PORT="443"
export SERVER_NAME="example.com"
export SERVER_ALIAS="www.example.com"
export DOCUMENT_ROOT="/var/www/html/"
envsubst < apache.tmpl > my_apache_site.conf
Ausgabe:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot "/var/www/html/"
</VirtualHost>
Lösung 3:
Außer /bin/sh
sind keine Tools erforderlich . Gegeben ist eine Vorlagendatei des Formulars
Version: ${version}
Path: ${path}
oder sogar mit gemischtem Shell-Code enthalten
Version: ${version}
Path: ${path}
Cost: ${cost}\$
$(i=1; for w in one two three four; do echo Param${i}: ${w}; i=$(expr $i + 1); done)
und eine Shell-Parsable-Konfigurationsdatei wie
version="1.2.3-r42"
path="/some/place/under/the/rainbow/where/files/dance/in/happiness"
cost="42"
es ist eine einfache Angelegenheit, dies zu erweitern zu
Version: 1.2.3-r42
Path: /some/place/under/the/rainbow/where/files/dance/in/happiness
Cost: 42$
Param1: one
Param2: two
Param3: three
Param4: four
Tatsächlich ist der Pfad zur Konfigurationsdatei in der Shell-Variablen config_file
angegeben und den Pfad zur Vorlagendatei in template_file
, alles, was Sie tun müssen, ist:
. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""
Das ist vielleicht schöner, als ein vollständiges Shell-Skript als Vorlagendatei zu haben (@mtinbergs Lösung).
Das komplette naive Template-Expander-Programm:
#!/bin/sh
PROG=$(basename $0)
usage()
{
echo "${PROG} <template-file> [ <config-file> ]"
}
expand()
{
local template="$(cat $1)"
eval "echo \"${template}\""
}
case $# in
1) expand "$1";;
2) . "$2"; expand "$1";;
*) usage; exit 0;;
esac
Dadurch wird die Erweiterung auf die Standardausgabe ausgegeben; leiten Sie einfach die Standardausgabe in eine Datei um oder ändern Sie das obige auf offensichtliche Weise, um die gewünschte Ausgabedatei zu erzeugen.
Warnhinweise: Die Erweiterung der Vorlagendatei funktionierte nicht, wenn die Datei doppelte Anführungszeichen ohne Escapezeichen enthielt ("
). Aus Sicherheitsgründen sollten wir wahrscheinlich einige offensichtliche Plausibilitätsprüfungen einschließen oder, noch besser, eine Shell-Escape-Transformation durchführen, wenn die Vorlagendatei von einer externen Entität generiert wird.
Lösung 4:
Wenn Sie statt Shell-Code, der neue Dateien generiert, einfache und echte Vorlagen wünschen, ist die übliche Auswahl sed
&awk
oder perl
. Hier ist ein Link:http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/
Ich würde eine echte Sprache wie Perl, TCL, Python, Ruby oder etwas anderes in dieser Klasse verwenden. Etwas, das für die Skripterstellung gebaut wurde. Sie alle haben gute, einfache Templating-Tools und jede Menge Beispiele in Google.
Lösung 5:
Ich benutze dafür shtpl. (privates Projekt von mir, das heißt, es ist nicht weit verbreitet. Aber vielleicht möchten Sie es trotzdem testen)
Wenn Sie zum Beispiel eine /etc/network/interfaces aus einer csv-Datei generieren möchten, können Sie das so machen:
Inhalt der CSV-Datei (hier test.csv):
eth0;10.1.0.10;255.255.0.0;10.1.0.1
eth1;192.168.0.10; 255.255.255.0;192.168.0.1
Vorlage (hier Interfaces.tpl):
#% IFS=';'
#% while read "Val1" "Val2" "Val3" "Val4"; do
auto $Val1
iface $Val1 inet static
address $Val2
netmask $Val3
gateway $Val4
#% done < "$CSVFILE"
Befehl:
$ CSVFILE=test.csv sh -c "$( shtpl interfaces.tpl )"
Ergebnis:
auto eth0
iface eth0 inet static
address 10.1.0.10
netmask 255.255.0.0
gateway 10.1.0.1
auto eth1
iface eth1 inet static
address 192.168.0.10
netmask 255.255.255.0
gateway 192.168.0.1
Viel Spaß!