Utwórz nowy plik z szablonów za pomocą skryptu bash

Muszę utworzyć pliki conf i init.d, które są bardzo podobne. Pliki te pozwalają wdrożyć nową usługę http na moich serwerach. Pliki te są takie same i tylko niektóre parametry zmieniają się z jednego pliku na drugi (listen_port, domena, ścieżka na serwerze...).

Ponieważ każdy błąd w tych plikach prowadzi do błędnego działania usługi, chciałbym utworzyć te pliki za pomocą skryptu bash.

Na przykład:

generate_new_http_service.sh 8282 subdomain.domain.com /home/myapp/rootOfHTTPService

Szukam pewnego rodzaju modułu szablonów, który mógłbym wykorzystać z bashem. To moduł szablonów używałby generycznych konf i init.Skrypty d do tworzenia nowych.

Masz na to wskazówki? Jeśli nie mogę użyć silnika szablonów Pythona.
Author: guaka, 2011-06-02

7 answers

Możesz to zrobić używając heredoc. np.

Generate.sh:

#!/bin/sh

#define parameters which are passed in.
PORT=$1
DOMAIN=$2

#define the template.
cat  << EOF
This is my template.
Port is $PORT
Domain is $DOMAIN
EOF

Wyjście:

$ generate.sh 8080 domain.com

This is my template.
Port is 8080
Domain is domain.com

Lub zapisz go do pliku:

$ generate.sh 8080 domain.com > result
 65
Author: dogbane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-02 13:23:54

Moduł szablonów dla bash? Użyj sed, Luke! Oto przykład jednego z milionów możliwych sposobów na zrobienie tego:

$ cat template.txt 
#!/bin/sh

echo Hello, I am a server running from %DIR% and listening for connection at %HOST% on port %PORT% and my configuration file is %DIR%/server.conf

$ cat create.sh 
#!/bin/sh

sed -e "s;%PORT%;$1;g" -e "s;%HOST%;$2;g" -e "s;%DIR%;$3;g" template.txt > script.sh

$ bash ./create.sh 1986 example.com /tmp
$ bash ./script.sh 
Hello, I am a server running from /tmp and listening for connection at example.com on port 1986 and my configuration file is /tmp/server.conf
$ 
 39
Author: Christian Toffolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-27 15:09:00

Możesz to zrobić bezpośrednio w bash, nawet nie potrzebujesz sed. Napisz taki skrypt:

#!/bin/bash

cat <<END
this is a template
with $foo
and $bar
END

Więc nazwij to tak:

foo=FOO bar=BAR ./template 
 18
Author: Kim Stebel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-02 13:24:25

Do prostego generowania plików, w zasadzie robiąc

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

Tutaj ${config_file} zawiera zmienne konfiguracyjne w formacie analizy powłoki, a {[2] } jest plikiem szablonu, który wygląda jak dokument powłoki tutaj. Pierwsza linia źródła w pliku ${config_file}, Druga linia umieszcza zawartość pliku ${template_file} do zmiennej powłoki template_str. Na koniec w trzeciej linii budujemy polecenie powłoki echo "${template_str}" (gdzie rozszerzone jest podwójne cytowane wyrażenie "${template_str}") i oceniamy to.

Aby uzyskać przykład zawartości tych dwóch plików, zapoznaj się z https://serverfault.com/a/699377/120756 .

Istnieją ograniczenia, które możesz mieć w pliku szablonu lub musisz wykonać ucieczkę powłoki. Również jeśli plik szablonu jest wytwarzany zewnętrznie, to ze względów bezpieczeństwa należy rozważyć wdrożenie odpowiedniego filtrowania przed wykonaniem, aby np. nie stracić plików, gdy ktoś wstrzyknie słynny $(rm -rf /) w plik szablonu.

 8
Author: FooF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 12:13:38

Oto podejście, które podjąłem, aby rozwiązać ten problem. Uważam, że jest trochę bardziej elastyczny niż niektóre z powyższych podejść i unika niektórych problemów z cytatami.

Fill.sh:

#!/usr/bin/env sh

config="$1"
template="$2"
destination="$3"

cp "$template" "$destination"

while read line; do
    setting="$( echo "$line" | cut -d '=' -f 1 )"
    value="$( echo "$line" | cut -d '=' -f 2- )"

    sed -i -e "s;%${setting}%;${value};g" "$destination"
done < "$config"

Szablon:

Template full of important %THINGS%

"Note that quoted %FIELDS% are handled correctly"

If I need %NEWLINES% then I can add them as well.

Config:

THINGS=stuff
FIELDS="values work too!"
NEWLINES="those\\nnifty\\nlinebreaks"

Wynik: Szablon pełen ważnych rzeczy

"Note that quoted "values work too!" are handled correctly"

If I need those
nifty
linebreaks then I can add them as well.
 2
Author: Keegs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-06 00:41:12

Oto jak zrobiłem dla siebie:

. "${config_file}"
eval "cat << EOF
$(cat ${template_file})
EOF"

I jeśli chcesz umieścić go w pliku konfiguracyjnym:

. "${config_file}"
eval "cat > /etc/MY_SERVICE/MY_CONFIG << EOF
$(cat ${template_file})
EOF"

W ten sposób nie musisz tworzyć dodatkowej zmiennej.

 0
Author: Samuel Phan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-07 15:55:29

Możesz użyć klasy Pythona string.Template

$ echo 'before $X after' > template.txt

$ python  -c 'import string; print(string.Template(open("template.txt").read()).substitute({"X":"A"}))'

before A after

Lub

$  python  -c 'import string, sys; print(string.Template(open("template.txt").read()).substitute({"X":sys.argv[1]}))' "A"

Tutaj $X jest symbolem zastępczym w szablonie, a {[5] } jest odwzorowaniem symbolu zastępczego na wartość. W kodzie Pythona odczytujemy tekst szablonu z pliku, tworzymy z niego szablon, a następnie zastępujemy go argumentem wiersza poleceń.

Alternatywnie możesz użyć ERB Rubiego, jeśli Ruby jest zainstalowany na twoim komputerze.

$ echo "before <%= ENV['X'] %> after" > template.txt

$ X=A erb template.txt

before A after

Tutaj <%= ENV['X'] %> jest symbolem zastępczym. ENV['X'] odczytuje wartość z zmienna środowiskowa. X=A ustawia zmienną środowiskową na żądaną wartość.

 0
Author: Alexey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-13 20:30:04