Frage Templating mit Linux in einem Shell Script?


Was ich will, ist:

1.) Eine Konfigurationsdatei als Vorlage haben, mit Variablen wie $ version $ path (zB apache config)

2.) Ein Shell-Skript, das die Variablen der Vorlage "ausfüllt" und die generierte Datei auf die Festplatte schreibt.

Ist das mit einem Shell-Skript möglich? Ich würde sehr dankbar sein, wenn Sie einige Befehle / Werkzeuge nennen können, die ich erreichen kann, oder einige gute Links.


21
2017-07-06 21:33


Ursprung




Antworten:


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 z

#! /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önnen dies auch in der Befehlszeile konfigurieren, indem Sie angeben version=$1 und path=$2, also kannst du es so ausführen bash script /foo/bar/baz 1.2.3. Das - Bevor EOF Leerzeichen verursacht, bevor die Zeilen ignoriert werden, verwenden Sie einfach <<EOF wenn du dieses Verhalten nicht willst.

Eine andere Möglichkeit wäre das Verwenden 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

das würde jede Instanz der Zeichenfolgen VERSION und PATH ersetzen. Wenn es andere Gründe dafür gibt, dass diese Zeichenfolgen in der Vorlagendatei enthalten sind, können Sie die Suche und den Austausch durchführen AUSFÜHRUNG oder% VERSION% oder etwas weniger wahrscheinlich versehentlich ausgelöst werden.


20
2017-07-06 21:41





Kein Werkzeug notwendig außer /bin/sh. Eine Vorlagedatei des Formulars gegeben

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 Sache, dies zu erweitern

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

In der Tat, angesichts des Pfades zur Konfigurationsdatei in der Shell-Variable config_file und der Pfad zur Vorlagendatei in template_fileAlles, was Sie tun müssen, ist:

. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""

Dies ist vielleicht hübscher als vollständiges Shell-Skript als Template-Datei 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. Umleiten Sie einfach die Standardausgabe in eine Datei oder ändern Sie das Obige in naheliegender Weise, um die gewünschte Ausgabedatei zu erzeugen.

Vorbehalte: Die Vorlagendateierweiterung funktionierte nicht, wenn die Datei unesparted doppelte Anführungszeichen enthielt ("). Aus Sicherheitsgründen sollten wir wahrscheinlich einige offensichtliche Plausibilitätsprüfungen einbeziehen oder, noch besser, Shell-entweichende Transformation durchführen, wenn die Vorlagendatei von einer externen Entität generiert wird.


12
2018-06-16 12:47



Es ist großartig, immer noch Leute zu sehen, die aktiv Shell-Skripte benutzen, um solche Sachen zu machen. Ein Kumpel von mir schrieb eine Uhr in Shell-Skript. github.com/tablespoon/fun/blob/master/cli-clock  Spaß mal in der Tat. - chicks
Als ich diese Antwort fand, als ich das selbst machen wollte, implementierte ich den ziemlich naiven Ansatz und postete ihn auf Github: github.com/nealian/bash-unsafetemplates - Pyrocater


Sie sollten wahrscheinlich in ein Konfigurationsmanagementsystem wie schauen Marionette oder Koch. Diese können leicht tun, was Sie oben beschreiben und viel Mehr.


4
2017-07-06 21:34



Vielen Dank. Absolut, ich habe Chef installiert und läuft. Aber es kostet viel Overhead, wenn Sie Ihre eigenen Kochbücher schreiben müssen. Ich kenne die Ruby-Programmiersprache nicht und meine Schlussfolgerung war. es ist einfacher, dies mit einem Shell-Skript für die leichteren Fälle (wenn möglich) zu tun. - Markus
Sieht aus wie Marionette und Koch Beide verwenden ERB für Vorlagen, und das ist unglaublich einfach. Gegeben eine Variable name, die Saite <%= name %> in einer Vorlage wird mit ersetzt nameder Wert. Wie definierst du? name außerhalb der Vorlage unterscheidet sich offensichtlich zwischen den beiden Systemen. - Mike Renfro
Ja Templating (mit Chef) selbst ist absolut einfach. Aber die Verwendung von Koch als Framework (und das Schreiben der Kochbücher) erfordert viel Zeit. Um die Daten in die Templates zu bekommen, müssen Sie verstehen, wo und wie Chef das "Zusammenführen" von Datenquellen und viele andere Dinge verwaltet. Ich habe angefangen, meine eigenen Kochbücher zu schreiben, aber ein Shell-Skript würde in meinem speziellen Fall 100 mal schneller sein ... - Markus
Es kann mühsam sein, die Infrastruktur für Chefkoch oder Puppet in Angriff zu nehmen, oder Sie können versuchen, herauszufinden, wie man sie kopflos führt, was ein lustiges Abenteuer ist. Ansible funktioniert problemlos im Pull- oder Push-Modus, so dass es besser ausbalanciert werden kann, um es herauszufinden und selbst zu scripten. docs.ansible.com/template_modul.html - chicks


Wenn Sie leichte und echte Vorlagen anstelle von Shell-Code, der neue Dateien generiert, wollen, sind die üblichen Möglichkeiten 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 Skripts erstellt wurde. Sie alle haben gute, einfache Vorlagenwerkzeuge und viele Beispiele in Google.


4
2017-07-06 21:43





ich benutze shtpl dafür. (privates Projekt von mir, das heißt, es ist nicht weit verbreitet. Aber vielleicht willst du es trotzdem testen)

Wenn Sie zum Beispiel ein / etc / network / interfaces aus einer CSV-Datei erzeugen wollen, 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

Genießen!


4
2017-10-21 17:52





Ich habe die Antwort von FooF verbessert, damit der Benutzer doppelte Anführungszeichen nicht manuell entfernen muss:

#!/bin/bash
template="$(cat $1)"
template=$(sed 's/\([^\\]\)"/\1\\"/g; s/^"/\\"/g' <<< "$template")
eval "echo \"${template}\""

1
2017-08-06 09:31





Ich bin wahrscheinlich zu spät zu dieser Party. Ich stolperte jedoch über das gleiche Problem und entschied mich für die Erstellung meiner eigenen BASH Template-Engine in ein paar Zeilen Code:

Lass uns sagen, dass du das hast file.template:

# My template
## Author
 - @NAME@ <@EMAIL@>

Und das rules Datei:

NAME=LEOPOLDO WINSTON
EMAIL=leothewinston\@leoserver.com

Sie führen diesen Befehl aus:

templater rules < file.template

Du bekommst das:

# My template
## Author
 - LEOPOLDO WINSTON <leothewinston@leoserver.com>

Sie können es installieren von:

 bpkg install vicentebolea/bash-templater

Das ist das Projekt Seite? ˅


0
2017-07-02 10:45