Szablony Bash: jak budować pliki konfiguracyjne z szablonów za pomocą Bash?
Piszę skrypt do automatyzacji tworzenia plików konfiguracyjnych dla Apache i PHP dla własnego serwera www. Nie chcę używać żadnych GUI, takich jak CPanel lub ISPConfig.
Mam kilka szablonów plików konfiguracyjnych Apache i PHP. Skrypt Bash musi odczytywać szablony, zastępować zmienne i wyprowadzać przetworzone szablony do jakiegoś folderu. Jak najlepiej to zrobić? Mogę wymyślić kilka sposobów. Który z nich jest najlepszy lub może być kilka lepszych sposobów, aby to zrobić? Chcę zrobić to w czystej Bash (jest to łatwe na przykład w PHP)
1) Jak zastąpić symbole zastępcze ${} w pliku tekstowym?
Szablon.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, jak przekierować wyjście do zewnętrznego pliku tutaj? Czy muszę czegoś unikać, jeśli zmienne zawierają, powiedzmy, cudzysłowy?
2) Użycie cat & sed do zastąpienia każdej zmiennej jej wartością:
Podany szablon.txt:
The number is ${i}
The word is ${word}
Polecenie:
cat template.txt | sed -e "s/\${i}/1/" | sed -e "s/\${word}/dog/"
Wydaje mi się źle z powodu potrzeby aby uniknąć wielu różnych symboli i wielu zmiennych linia będzie zbyt długa.
Czy możesz wymyślić jakieś inne eleganckie i bezpieczne rozwiązanie?21 answers
Możesz użyć tego:
perl -p -i -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : $&/eg' < template.txt
Zastąpienie wszystkich łańcuchów ${...}
odpowiednimi zmiennymi środowiska (nie zapomnij wyeksportować ich przed uruchomieniem tego skryptu).
Dla czystego Basha powinno to działać (zakładając, że zmienne nie zawierają ${...} ciągi):
#!/bin/bash
while read -r line ; do
while [[ "$line" =~ (\$\{[a-zA-Z_][a-zA-Z_0-9]*\}) ]] ; do
LHS=${BASH_REMATCH[1]}
RHS="$(eval echo "\"$LHS\"")"
line=${line//$LHS/$RHS}
done
echo "$line"
done
. Rozwiązanie, które nie zawiesza się, jeśli RHS odwołuje się do jakiejś zmiennej, która odwołuje się do siebie:
#!/bin/bash line="$(cat; echo -n a)" end_offset=${#line} while [[ "${line:0:$end_offset}" =~ (.*)(\$\{([a-zA-Z_][a-zA-Z_0-9]*)\})(.*) ]] ; do PRE="${BASH_REMATCH[1]}" POST="${BASH_REMATCH[4]}${line:$end_offset:${#line}}" VARNAME="${BASH_REMATCH[3]}" eval 'VARVAL="$'$VARNAME'"' line="$PRE$VARVAL$POST" end_offset=${#PRE} done echo -n "${line:0:-1}"
WARNING: Nie wiem jak poprawnie obsłużyć input z NULs w bash lub preserve ilość kończących się nowych linii. Ostatni wariant jest przedstawiony tak, ponieważ "love" Binary input:
-
read
zinterpretuje ukośniki. -
read -r
nie zinterpretuje ukośników wstecznych, ale i tak upuści ostatnią linię, jeśli nie zakończy się nową linią. -
"$(…)"
usunie tyle nowych znaków, ile jest obecnych, więc kończę…
z; echo -n a
i użyjęecho -n "${line:0:-1}"
: to usunie ostatni znak (który jesta
) i zachowa tyle nowych znaków, ile było na wejściu (w tym nie).
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-12-18 22:23:43
Try envsubst
FOO=foo
BAR=bar
export FOO BAR
envsubst <<EOF
FOO is $FOO
BAR is $BAR
EOF
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
2012-06-15 12:48:40
Envsubst był dla mnie nowy. Fantastycznie.
Dla przypomnienia, użycie heredoc jest świetnym sposobem na szablon pliku conf.
STATUS_URI="/hows-it-goin"; MONITOR_IP="10.10.2.15";
cat >/etc/apache2/conf.d/mod_status.conf <<EOF
<Location ${STATUS_URI}>
SetHandler server-status
Order deny,allow
Deny from all
Allow from ${MONITOR_IP}
</Location>
EOF
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
2012-08-17 13:33:14
Zgadzam się z używaniem sed: jest to najlepsze narzędzie do wyszukiwania/zastępowania. Oto moje podejście:
$ cat template.txt
the number is ${i}
the dog's name is ${name}
$ cat replace.sed
s/${i}/5/
s/${name}/Fido/
$ sed -f replace.sed template.txt > out.txt
$ cat out.txt
the number is 5
the dog's name is Fido
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
2010-05-26 18:13:52
Myślę, że eval działa naprawdę dobrze. Obsługuje szablony z przerwami liniowymi, białymi spacjami i wszelkiego rodzaju materiałami bash. Jeśli masz pełną kontrolę nad samymi szablonami oczywiście:
$ cat template.txt
variable1 = ${variable1}
variable2 = $variable2
my-ip = \"$(curl -s ifconfig.me)\"
$ echo $variable1
AAA
$ echo $variable2
BBB
$ eval "echo \"$(<template.txt)\"" 2> /dev/null
variable1 = AAA
variable2 = BBB
my-ip = "11.22.33.44"
Tę metodę należy oczywiście stosować ostrożnie, ponieważ eval może wykonać dowolny kod. Uruchamianie tego jako root nie wchodzi w grę. Cytaty w szablonie muszą być unikalne, w przeciwnym razie zostaną zjedzone przez eval
.
Możesz również użyć tutaj dokumentów, jeśli wolisz cat
, Aby echo
$ eval "cat <<< \"$(<template.txt)\"" 2> /dev/null
@plockc napisał rozwiązanie, które pozwala uniknąć problemu z cytowaniem Basha:
$ eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null
Edit: usunięto część o uruchomieniu tego jako root przy użyciu sudo...
Edit: Dodano komentarz o tym, jak należy unikać cytatów, dodano rozwiązanie płockc do miksu!
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-10-17 12:41:57
Edycja 6 Stycznia 2017
Musiałem zachować podwójne cudzysłowy w moim pliku konfiguracyjnym, więc podwójne unikanie podwójnych cudzysłowów z sed pomaga:
render_template() {
eval "echo \"$(sed 's/\"/\\\\"/g' $1)\""
}
Nie mogę myśleć o ciągnięciu nowych linii, ale puste linie pomiędzy są utrzymywane.
Chociaż jest to stary temat, IMO znalazłem bardziej eleganckie rozwiązanie tutaj: http://pempek.net/articles/2013/07/08/bash-sh-as-template-engine/
#!/bin/sh
# render a template configuration file
# expand variables + preserve formatting
render_template() {
eval "echo \"$(cat $1)\""
}
user="Gregory"
render_template /path/to/template.txt > path/to/configuration_file
Wszystkie napisy dla Grégory Pakosz.
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-01-06 14:26:43
Mam rozwiązanie bash jak mogsie, ale z heredoc zamiast herestring, aby uniknąć unikania podwójnych cudzysłowów
eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null
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-07-25 16:19:40
Dłuższa, ale solidniejsza wersja zaakceptowanej odpowiedzi:
perl -pe 's;(\\*)(\$([a-zA-Z_][a-zA-Z_0-9]*)|\$\{([a-zA-Z_][a-zA-Z_0-9]*)\})?;substr($1,0,int(length($1)/2)).($2&&length($1)%2?$2:$ENV{$3||$4});eg' template.txt
To rozszerza wszystkie instancje $VAR
lub ${VAR}
do ich wartości środowiskowych (lub, jeśli są niezdefiniowane, pusty łańcuch).
Poprawnie unika ukośników wstecznych i akceptuje ukośnik wsteczny-escaped $ w celu zahamowania substytucji(w przeciwieństwie do envsubst, który, jak się okazuje, tego nie robi ).
Więc jeśli twoje środowisko to:
FOO=bar
BAZ=kenny
TARGET=backslashes
NOPE=engi
A Twój szablon to:
Two ${TARGET} walk into a \\$FOO. \\\\
\\\$FOO says, "Delete C:\\Windows\\System32, it's a virus."
$BAZ replies, "\${NOPE}s."
The wynik będzie:
Two backslashes walk into a \bar. \\
\$FOO says, "Delete C:\Windows\System32, it's a virus."
kenny replies, "${NOPE}s."
Jeśli chcesz tylko uniknąć ukośników przed $ (możesz napisać "C:\Windows\System32" W szablonie bez zmian), użyj tej nieco zmodyfikowanej wersji:
perl -pe 's;(\\*)(\$([a-zA-Z_][a-zA-Z_0-9]*)|\$\{([a-zA-Z_][a-zA-Z_0-9]*)\});substr($1,0,int(length($1)/2)).(length($1)%2?$2:$ENV{$3||$4});eg' template.txt
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-03-25 17:57:33
Zrobiłbym to w ten sposób, prawdopodobnie mniej wydajny, ale łatwiejszy do odczytania / utrzymania.
TEMPLATE='/path/to/template.file'
OUTPUT='/path/to/output.file'
while read LINE; do
echo $LINE |
sed 's/VARONE/NEWVALA/g' |
sed 's/VARTWO/NEWVALB/g' |
sed 's/VARTHR/NEWVALC/g' >> $OUTPUT
done < $TEMPLATE
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
2010-05-28 11:07:05
Jeśli chcesz użyć szablonów Jinja2 , zobacz ten projekt: j2cli.
Obsługuje:
- szablony z plików JSON, ini, YAML i strumieni wejściowych
- Tworzenie szablonów ze zmiennych środowiskowych
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-06-25 15:16:58
Biorąc odpowiedź od ZyX używając czystego Basha, ale z dopasowaniem regex w Nowym stylu i pośrednim podstawianiem parametrów staje się:
#!/bin/bash
regex='\$\{([a-zA-Z_][a-zA-Z_0-9]*)\}'
while read line; do
while [[ "$line" =~ $regex ]]; do
param="${BASH_REMATCH[1]}"
line=${line//${BASH_REMATCH[0]}/${!param}}
done
echo $line
done
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-10-22 14:17:09
Jeśli używasz Perl jest opcją i jesteś zadowolony z bazowania rozszerzeń na środowisko zmienne tylko (W przeciwieństwie do wszystkich Shell zmienne), rozważmy solidną odpowiedź Stuarta P. Bentleya.
Ta odpowiedź ma na celu dostarczenie tylko bash rozwiązanie , które-pomimo użycia eval
- powinno być bezpieczne w użyciu .
Cele to:
- wsparcie zarówno
${name}
jak i$name
odniesienia do zmiennych. - Zapobiegaj wszelkim innym rozszerzeniom:
- command substitutions (
$(...)
and legacy syntax`...`
) - podstawienia arytmetyczne (
$((...))
i składnia dziedziczenia$[...]
).
- command substitutions (
- umożliwiają selektywne tłumienie rozszerzalności zmiennej poprzez prefiks z
\
(\${name}
). - Zachowaj znaki specjalne. w danych wejściowych, w szczególności
"
i\
. - Zezwalaj na wprowadzanie przez argumenty lub przez stdin.
Funkcja expandVars()
:
expandVars() {
local txtToEval=$* txtToEvalEscaped
# If no arguments were passed, process stdin input.
(( $# == 0 )) && IFS= read -r -d '' txtToEval
# Disable command substitutions and arithmetic expansions to prevent execution
# of arbitrary commands.
# Note that selectively allowing $((...)) or $[...] to enable arithmetic
# expressions is NOT safe, because command substitutions could be embedded in them.
# If you fully trust or control the input, you can remove the `tr` calls below
IFS= read -r -d '' txtToEvalEscaped < <(printf %s "$txtToEval" | tr '`([' '\1\2\3')
# Pass the string to `eval`, escaping embedded double quotes first.
# `printf %s` ensures that the string is printed without interpretation
# (after processing by by bash).
# The `tr` command reconverts the previously escaped chars. back to their
# literal original.
eval printf %s "\"${txtToEvalEscaped//\"/\\\"}\"" | tr '\1\2\3' '`(['
}
Przykłady:
$ expandVars '\$HOME="$HOME"; `date` and $(ls)'
$HOME="/home/jdoe"; `date` and $(ls) # only $HOME was expanded
$ printf '\$SHELL=${SHELL}, but "$(( 1 \ 2 ))" will not expand' | expandVars
$SHELL=/bin/bash, but "$(( 1 \ 2 ))" will not expand # only ${SHELL} was expanded
- ze względu na wydajność, funkcja odczytuje wszystkie wejścia stdin naraz do pamięci, ale łatwo jest dostosować funkcję do podejścia linia po linii.
- obsługuje również niestandardowe rozszerzenia zmiennych, takie jak
${HOME:0:10}
, o ile nie zawierają wbudowanych poleceń lub podstawień arytmetycznych, takich jak${HOME:0:$(echo 10)}
- takie wbudowane podstawienia faktycznie łamią funkcję (ponieważ wszystkie
$(
i`
instancje są ślepo uciekane). - podobnie zniekształcone odwołania do zmiennych, takie jak
${HOME
(brak zamknięcia}
), przerywają funkcję.
- takie wbudowane podstawienia faktycznie łamią funkcję (ponieważ wszystkie
- ze względu na obsługę przez Basha podwójnych cytowanych łańcuchów, ukośniki są obsługiwane w następujący sposób:
-
\$name
zapobiega ekspansji. - pojedynczy
\
, po którym nie następuje$
jest zachowany w stanie takim, w jakim jest. - jeśli chcesz reprezentować wiele sąsiadujących
\
instancje, musisz podwoić them ; np.:-
\\
->\
- to samo co tylko\
-
\\\\
->\\
-
- wejście nie może zawierać następujących (rzadko używanych) znaków, które są używane do celów wewnętrznych:
0x1
,0x2
,0x3
.
-
- istnieje hipotetyczna obawa, że jeśli bash wprowadzi nową składnię rozszerzeń, ta funkcja może nie zapobiegać takim rozszerzeniom - zobacz poniżej rozwiązanie, które nie używa
eval
.
Jeśli szukasz bardziej restrykcyjnego rozwiązania, które tylko obsługuje ${name}
rozszerzenia - tj. z obowiązkowe nawiasy klamrowe, ignorując $name
odniesienia - patrz ta odpowiedź mojej.
Oto ulepszona wersja bash-only, eval
-FREE solution from the accepted answer:
Ulepszenia to:
- wsparcie dla rozszerzenia zarówno
${name}
jak i$name
odwołania do zmiennych. - wsparcie dla
\
-uciekających odniesień do zmiennych, które nie powinny być rozszerzane. - W przeciwieństwie do powyższego rozwiązania
eval
,- Nie-podstawowe rozszerzenia są ignorowane
- odniesienia do zmiennych zniekształconych są ignorowane (nie łamią skryptu)
IFS= read -d '' -r lines # read all input from stdin at once
end_offset=${#lines}
while [[ "${lines:0:end_offset}" =~ (.*)\$(\{([a-zA-Z_][a-zA-Z_0-9]*)\}|([a-zA-Z_][a-zA-Z_0-9]*))(.*) ]] ; do
pre=${BASH_REMATCH[1]} # everything before the var. reference
post=${BASH_REMATCH[5]}${lines:end_offset} # everything after
# extract the var. name; it's in the 3rd capture group, if the name is enclosed in {...}, and the 4th otherwise
[[ -n ${BASH_REMATCH[3]} ]] && varName=${BASH_REMATCH[3]} || varName=${BASH_REMATCH[4]}
# Is the var ref. escaped, i.e., prefixed with an odd number of backslashes?
if [[ $pre =~ \\+$ ]] && (( ${#BASH_REMATCH} % 2 )); then
: # no change to $lines, leave escaped var. ref. untouched
else # replace the variable reference with the variable's value using indirect expansion
lines=${pre}${!varName}${post}
fi
end_offset=${#pre}
done
printf %s "$lines"
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-05-23 11:47:29
Ta strona opisuje odpowiedź z awk
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < input.txt > output.txt
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
2012-03-06 19:39:52
Idealny futerał na shtpl . (mój projekt, więc nie jest szeroko stosowany i brakuje w dokumentacji. Ale oto rozwiązanie, które oferuje w każdym razie. Może chcesz to przetestować.)
Po prostu wykonaj:
$ i=1 word=dog sh -c "$( shtpl template.txt )"
Wynik to:
the number is 1
the word is dog
Baw się dobrze.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
2013-03-03 17:24:14
Oto kolejne rozwiązanie pure bash:
- używa heredoc, więc:
- złożoność nie wzrasta ze względu na dodatkową wymaganą składnię
- szablon może zawierać kod bash
- to również pozwala poprawnie wciąć rzeczy. Patrz poniżej.
- nie używa evalu, więc:
- brak problemów z renderowaniem końcowych pustych linii
- brak problemów z cytatami w szablon
$ cat code
#!/bin/bash
LISTING=$( ls )
cat_template() {
echo "cat << EOT"
cat "$1"
echo EOT
}
cat_template template | LISTING="$LISTING" bash
$ cat template
(z końcowymi znakami nowej linii i podwójnymi cudzysłowami)
<html>
<head>
</head>
<body>
<p>"directory listing"
<pre>
$( echo "$LISTING" | sed 's/^/ /' )
<pre>
</p>
</body>
</html>
Wyjście
<html>
<head>
</head>
<body>
<p>"directory listing"
<pre>
code
template
<pre>
</p>
</body>
</html>
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-02-18 11:52:16
Oto inne rozwiązanie: wygenerować skrypt bash ze wszystkimi zmiennymi i zawartością pliku szablonu, skrypt ten wyglądałby tak:
word=dog
i=1
cat << EOF
the number is ${i}
the word is ${word}
EOF
Jeśli dodamy ten skrypt do Basha, wygenerujemy żądane wyjście:
the number is 1
the word is dog
Oto jak wygenerować ten skrypt i wprowadzić go do Basha:
(
# Variables
echo word=dog
echo i=1
# add the template
echo "cat << EOF"
cat template.txt
echo EOF
) | bash
Dyskusja
- nawiasy otwierają sub powłokę, jej celem jest zgrupowanie wszystkich wygenerowanych wyników
- wewnątrz sub shell, generujemy wszystkie deklaracje zmiennych
- również w powłoce sub generujemy polecenie
cat
z HEREDOC - wreszcie, karmimy wyjście sub shell do bash i produkować żądane wyjście
-
Jeśli chcesz przekierować to wyjście do pliku, zastąp ostatnią linię przez:
) | bash > output.txt
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-04-04 15:00:02
Możesz również użyć bashible (który wewnętrznie wykorzystuje podejście oceniające opisane powyżej/poniżej).
Jest przykład, jak wygenerować HTML z wielu części:
Https://github.com/mig1984/bashible/tree/master/examples/templates
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-09-03 13:30:47
# Usage: template your_file.conf.template > your_file.conf
template() {
local IFS line
while IFS=$'\n\r' read -r line ; do
line=${line//\\/\\\\} # escape backslashes
line=${line//\"/\\\"} # escape "
line=${line//\`/\\\`} # escape `
line=${line//\$/\\\$} # escape $
line=${line//\\\${/\${} # de-escape ${ - allows variable substitution: ${var} ${var:-default_value} etc
# to allow arithmetic expansion or command substitution uncomment one of following lines:
# line=${line//\\\$\(/\$\(} # de-escape $( and $(( - allows $(( 1 + 2 )) or $( command ) - UNSECURE
# line=${line//\\\$\(\(/\$\(\(} # de-escape $(( - allows $(( 1 + 2 ))
eval "echo \"${line}\"";
done < "$1"
}
Jest to czysta funkcja bash dostosowana do Twoich upodobań, używana w produkcji i nie powinna pękać na żadnym wejściu. Jeśli się zepsuje - daj mi znać.
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-10-12 18:50:21
Oto funkcja bash, która zachowuje białe znaki:
# Render a file in bash, i.e. expand environment variables. Preserves whitespace.
function render_file () {
while IFS='' read line; do
eval echo \""${line}"\"
done < "${1}"
}
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-01-01 03:27:00
Oto zmodyfikowany skrypt perl
oparty na kilku innych odpowiedziach:
perl -pe 's/([^\\]|^)\$\{([a-zA-Z_][a-zA-Z_0-9]*)\}/$1.$ENV{$2}/eg' -i template
Funkcje (w oparciu o moje potrzeby, ale powinny być łatwe do modyfikacji):
- pomija rozszerzenia parametrów ucieczki (np. \${VAR}).
- Obsługuje rozszerzenia parametrów postaci ${VAR}, ale nie $VAR.
- zastępuje ${VAR} pustym łańcuchem, jeśli nie ma VAR envar.
- obsługuje tylko a-z, A-Z, 0-9 i znaki podkreślenia w nazwie (z wyłączeniem cyfr na pierwszej pozycji).
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-12-22 02:02:54
Zamiast wymyślać koło idź z envsubst Może być stosowany w prawie każdym scenariuszu, na przykład do budowania plików konfiguracyjnych ze zmiennych środowiskowych w kontenerach docker.
Jeśli na Macu upewnij się, że masz homebrew to podlinkuj go z gettext:
brew install gettext
brew link --force gettext
./ szabloncfg
# We put env variables into placeholders here
this_variable_1 = ${SOME_VARIABLE_1}
this_variable_2 = ${SOME_VARIABLE_2}
./.env:
SOME_VARIABLE_1=value_1
SOME_VARIABLE_2=value_2
./configure.sh
#!/bin/bash
cat template.cfg | envsubst > whatever.cfg
Teraz wystarczy użyć:
# make script executable
chmod +x ./configure.sh
# source your variables
. .env
# export your variables
# In practice you may not have to manually export variables
# if your solution dependins on tools that utilise .env file
# automatically like pipenv etc.
export SOME_VARIABLE_1 SOME_VARIABLE_2
# Create your config file
./configure.sh
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-08-31 08:45:07