Возможно ли на bash отрендерить какой-нибудь шаблон? Например, как в ansible? Конечно возможно! Сейчас покажу.
Давай возьмем огрызок конфига nginx и сделаем из него шаблон под разное окружение. У меня будет 2 сервера, естественно production и до кучи возьмем stage.
Создаем шаблон: nginx.tpl
Еще есть фича с созданием файла через
Так, поехали рендерить:
Далее вызываем функцию render и передаем в нее nginx_user и pid_path. Функция render всё это дело экспортирует в переменные окружения, а затем с помощью envsubst заменяет их в шаблоне. Готовый конфиг сразу попадает в папку с nginx.Охуенно! Кайф!
envsubst - заменяет переменную окружения новым значением в формате строки оболочки командной строки. Переменные могут быть заменены в формате ${var} или $var
Если у тебя много переменных, то можешь их разом экспортировать через цикл. В предыдущих постах у меня где-то есть примеры таких циклов.
Собственно на этом можно и заканчивать. В 99% случаев все используют какой-то вонючий perl, sed, eval и т.п. Но решение с envsubst намного гибче и элегантнее.
Есть еще вариант с Heredoc. Heredoc-синтаксис — способ определения строковых переменных в исходном коде программ.
Пример скрипта, делает то же самое. Логику добавлять не стал:
tags: #linux #bash
—
💩 @bashdays
Давай возьмем огрызок конфига nginx и сделаем из него шаблон под разное окружение. У меня будет 2 сервера, естественно production и до кучи возьмем stage.
Создаем шаблон: nginx.tpl
user ${nginx_user};Всё то, что нужно отрендерить, располагаем в
worker_processes auto;
pid ${pid_path};
include /etc/nginx/modules/*.conf
${параметр}.
Создаем скрипт с логикой:>> nginx_gen.sh && chmod +x nginx_gen.shСимволы «>>» означают - создать новый файл. А чмодиком делаем файл покорным и исполняемым.
Еще есть фича с созданием файла через
touch nginx_gen.sh.
Если запустить команду с touch повторно, то файл не перетрется, НО у него обновится дата и время создания. Иногда бывает полезно обновлять дату и время каким-нибудь файлам, которые выполняют роль флагов.Так, поехали рендерить:
#!/bin/bashРазбираем портянку. Логика простая, если hostname равен production, то присваиваем одни переменные. Во всех других случаях присваиваем другие переменные.
function render {
export nginx_user=$1 pid_path=$2
cat nginx.tpl | envsubst > /etc/nginx/nginx.conf
}
if [[ $(hostname) == "production" ]]; then
nginx_user="www-data"
pid_path="/run/nginx.pid"
render $nginx_user $pid_path
else
nginx_user="nginx"
pid_path="/var/run/nginx.pid"
render $nginx_user $pid_path
fi
Далее вызываем функцию render и передаем в нее nginx_user и pid_path. Функция render всё это дело экспортирует в переменные окружения, а затем с помощью envsubst заменяет их в шаблоне. Готовый конфиг сразу попадает в папку с nginx.
envsubst - заменяет переменную окружения новым значением в формате строки оболочки командной строки. Переменные могут быть заменены в формате ${var} или $var
Если у тебя много переменных, то можешь их разом экспортировать через цикл. В предыдущих постах у меня где-то есть примеры таких циклов.
Собственно на этом можно и заканчивать. В 99% случаев все используют какой-то вонючий perl, sed, eval и т.п. Но решение с envsubst намного гибче и элегантнее.
Есть еще вариант с Heredoc. Heredoc-синтаксис — способ определения строковых переменных в исходном коде программ.
Пример скрипта, делает то же самое. Логику добавлять не стал:
#!/bin/bashОтрендерится как нужно, но мне все же ближе вариант с envsubst. Нагляднее чтоли. Выбор лишь за тобой, на каком велосипеде кататься. Вот такие пироги. Ладно, побежал я дальше работу работать. Будьте здоровы! Увидимся!
nginx_user="www-data"
pid_path="/var/run/nginx.pid"
cat > /etc/nginx/nginx.conf << EOF
user ${nginx_user};
worker_processes auto;
pid ${pid_path};
include /etc/nginx/modules-enabled/*.conf;
EOF
tags: #linux #bash
—