Bash Templating: Wie man Konfigurationsdateien aus Vorlagen mit Bash erstellt?
Ich Schreibe ein Skript zum automatisieren der Erstellung von Konfigurationsdateien für Apache und PHP auf meinem eigenen webserver. Ich will nicht von irgendwelchen GUIs, wie CPanel oder ISPConfig.
Ich habe einige Vorlagen von PHP und Apache-Konfigurationsdateien. Bash-Skript Lesen muss Vorlagen, machen Variablenzuweisung und Ausgabe analysiert Vorlagen in einem Ordner. Was ist der beste Weg, das zu tun? Ich kann mir denken, von mehreren Möglichkeiten. Welche ist die beste oder vielleicht gibt es einige bessere Möglichkeiten, das zu tun? Ich möchte zu tun, dass in reinen Bash (es ist einfach, in PHP zum Beispiel)
1) So ersetzen Sie $ {} - Platzhalter in eine text-Datei?
template.txt:
the number is ${i}
the word is ${word}
script.sh:
#!/bin/sh
#set variables
i=1
word="dog"
#read in template one line at the time, and replace variables
#(more natural (and efficient) way, thanks to Jonathan Leffler)
while read line
do
eval echo "$line"
done < "./template.txt"
BTW, wie kann ich die Umleitung der Ausgabe auf externen Datei hier? Brauche ich, um zu entkommen etwas, wenn Sie Variablen enthalten, sagen, Zitate?
2) Mit Hilfe von cat & sed für die Ersetzung der einzelnen Variablen durch Ihren Wert:
Gegeben template.txt:
The number is ${i}
The word is ${word}
Befehl:
cat template.txt | sed -e "s/\${i}/1/" | sed -e "s/\${word}/dog/"
Schlecht scheint mir wegen der zu entkommen müssen viele verschiedene Symbole und mit vielen Variablen die Zeile tooooo lange.
Können Sie sich einige andere elegante und sichere Lösung?
InformationsquelleAutor der Frage Vladislav Rastrusny | 2010-05-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese:
ersetzen alle
${...}
strings mit entsprechenden Umgebungs-Variablen (nicht vergessen zu exportieren, um Sie vor dem ausführen dieses Skripts).Für Reine bash sollte das funktionieren (vorausgesetzt, die Variablen sind nicht enthalten $ { ... } - strings):
. Lösung, die nicht hängen, wenn RHS Referenzen einige Variablen, die Referenzen selbst:
WARNUNG: ich weiß nicht, einen Weg, um richtig behandeln-Eingang mit NULs in bash oder bewahren Sie die Menge der nachfolgende Zeilenumbrüche. Die Letzte Variante wird vorgestellt, wie es ist, weil Muscheln "Liebe" binary input:
read
interpretiert backslashes.read -r
wird nicht interpretiert backslashes, aber immer noch sinkt die Letzte Zeile, wenn es endet nicht mit einem newline."$(…)"
Streifen als viele nachfolgende Zeilenumbrüche da sind vorhanden, so dass ich am Ende…
mit; echo -n a
und verwendenecho -n "${line:0:-1}"
: dies löscht das Letzte Zeichen (das ista
) und bewahrt so viele nachfolgende Zeilenumbrüche, wie es war, in die Eingabe (einschließlich keine).InformationsquelleAutor der Antwort ZyX
Versuchen
envsubst
InformationsquelleAutor der Antwort yottatsa
envsubst war mir neu. Fantastisch.
Für die Aufzeichnung, mit einem heredoc ist ein guter Weg, um Vorlage einer conf-Datei.
InformationsquelleAutor der Antwort Dan Garthwaite
Stimme ich mit sed: es ist das beste Werkzeug für das suchen/ersetzen. Hier ist mein Ansatz:
InformationsquelleAutor der Antwort Hai Vu
Ich denke eval funktioniert wirklich gut. Er verarbeitet Vorlagen mit Zeilenumbrüche, Leerzeichen, und alle Arten von bash Zeug. Wenn Sie haben die volle Kontrolle über die Vorlagen selbst natürlich:
Diese Methode sollte mit Vorsicht verwendet werden, da eval kann, beliebigen code auszuführen. Ausgeführt als root ist so ziemlich außer Frage. Zitate, die in der Vorlage müssen maskiert werden, sonst werden Sie gefressen
eval
.Können Sie auch hier Dokumente, wenn Sie es vorziehen
cat
zuecho
@plockc provoded eine Lösung, die vermeidet, dass die bash-quote escaping-Problem:
Edit: Entfernt Teil zum ausführen als root mit sudo...
Edit: Hinzugefügt Kommentar darüber, wie Zitate müssen escaped werden, Hinzugefügt plockc die Lösung für das mischen!
InformationsquelleAutor der Antwort mogsie
Bearbeiten, Jan 6, 2017
Ich benötigt, um doppelte Anführungszeichen in meiner Konfiguration-Datei, so double escaping von double-quotes mit sed hilft:
Kann ich nicht denken, um nachfolgende neue Zeilen, leere Zeilen dazwischen gehalten werden.
Es ist zwar ein altes Thema, IMO fand ich heraus, elegantere Lösung hier: http://pempek.net/articles/2013/07/08/bash-sh-as-template-engine/
Alle Kredite an Grégory Pakosz.
InformationsquelleAutor der Antwort CKK
Habe ich ein bash-Lösung wie mogsie aber mit der heredoc-statt herestring Ihnen zu erlauben, vermeiden, entkommen Anführungszeichen
InformationsquelleAutor der Antwort plockc
Ich würde getan haben, es auf diese Weise wahrscheinlich weniger effizient, aber einfacher zu Lesen/warten.
InformationsquelleAutor der Antwort Craig552uk
Länger, aber robustere version der akzeptierten Antwort:
Diese erweitert alle Instanzen von
$VAR
oder${VAR}
zu Ihrer Umwelt-Werten (oder, wenn Sie undefined ist, wird die leere Zeichenfolge).Es richtig entweicht, umgekehrte Schrägstriche, und akzeptiert eine backslash-Escape - $ zu hemmen substitution (im Gegensatz zu envsubst, die es stellt sich heraus, dies nicht tut).
Also, wenn Ihre Umgebung:
und Ihre Vorlage:
das Ergebnis wäre:
Wenn Sie nur wollen, zu entkommen Backslash vor dem $ (man könnte schreiben "C:\Windows\System32" in einer Vorlage unverändert), verwenden Sie diese leicht modifizierte version:
InformationsquelleAutor der Antwort Stuart P. Bentley
Wenn Sie verwenden möchten Jinja2 Vorlagen finden Sie dieses Projekt: j2cli.
Unterstützt:
InformationsquelleAutor der Antwort kolypto
Unter der Antwort von ZyX mit reinen bash, aber mit neuen Stil regex-matching und indirekte parameter-substitution wird es:
InformationsquelleAutor der Antwort wich
Wenn mit Perl eine option ist, und du damit zufrieden bist, mit stützend-Erweiterungen auf Umgebung Variablen nur (im Gegensatz zu allen shell Variablen), betrachten Stuart P. Bentley robuste Antwort.
Diese Antwort zielt darauf ab, eine bash-only-Lösungdass - trotz Verwendung von
eval
- sollte sicher zu verwenden.Den Ziele sind:
${name}
und$name
variable referenziert.$(...)
- und legacy-syntax`...`
)$((...))
- und legacy-syntax$[...]
).\
(\${name}
)."
und\
Instanzen.Funktion
expandVars()
:Beispiele:
${HOME:0:10}
solange Sie enthalten keine eingebetteten Befehl oder arithmetische Substitutionen, wie${HOME:0:$(echo 10)}
$(
und`
Instanzen sind blind geflohen).${HOME
(fehlendes}
) BRECHEN Sie die Funktion.\$name
verhindert die expansion.\
nicht gefolgt von$
erhalten ist, wie Sie ist.\
Instanzen, müssen Sie doppelklicken Sie; z.B.:\\
->\
- das gleiche wie gerade\
\\\\
->\\
0x1
0x2
0x3
.eval
.Wenn Sie sich für eine restriktivere Lösung, die nur unterstützt
${name}
Erweiterungen - d.h., mit zwingend geschweiften Klammern, ignorieren$name
Referenzen - siehe diese Antwort von mir.Hier ist ein verbesserte version der bash-nur
eval
-freie Lösung von der akzeptierte Antwort:Verbesserungen sind:
${name}
und$name
variable referenziert.\
-Flucht-variable referenziert, das sollte nicht erweitert werden.eval
-basierte Lösung vor,InformationsquelleAutor der Antwort mklement0
Diese Seite beschreibt ein Antwort mit awk
InformationsquelleAutor der Antwort Matt Brown
Perfekte Fall für shtpl. (Projekt von mir, also es ist nicht weit verbreitet und fehlt in der Dokumentation. Aber hier ist die Lösung bietet es jedenfalls. Können Sie es testen wollen.)
Nur ausführen:
Ergebnis ist:
Spaß haben.
InformationsquelleAutor der Antwort zstegi
Hier ist ein reines bash-Lösung:
$ cat code
$ cat template
(mit nachfolgenden Zeilenumbrüche und Anführungszeichen)Ausgabe
InformationsquelleAutor der Antwort Tomáš Pospíšek
Hier ist eine andere Lösung: erstellen Sie ein bash-script mit den Variablen und den Inhalt der template-Datei, das script würde so Aussehen:
Wenn wir füttern dieses Skript in bash wäre es erzeugen Sie die gewünschte Ausgabe:
Hier ist, wie zu generieren, das Skript und Futter, das Skript in bash:
Diskussion
cat
Befehl mit der HEREDOC -Wenn Sie möchten, leiten Sie diese Ausgabe in eine Datei, ersetzen Sie die Letzte Zeile mit:
InformationsquelleAutor der Antwort Hai Vu
Können Sie auch bashible (intern verwendet die Bewertung der beschriebenen Methode oben/unten).
Es ist ein Beispiel, das generieren von HTML aus mehreren teilen:
https://github.com/mig1984/bashible/tree/master/examples/templates
InformationsquelleAutor der Antwort Jan Molič
Dies ist die Reine bash-Funktion einstellbar nach Ihren wünschen, in der Produktion verwendet und sollten nicht brechen, die auf jede Eingabe.
Wenn es bricht - lass es mich wissen.
InformationsquelleAutor der Antwort ttt
Hier ist eine bash-Funktion, die bewahrt whitespace:
InformationsquelleAutor der Antwort Igor Katson
Hier ist eine modifizierte
perl
script basiert auf ein paar andere Antworten:Features (basierend auf meine Bedürfnisse, aber sollte leicht zu ändern):
InformationsquelleAutor der Antwort Kevin