Возможно ли на bash отрендерить какой-нибудь шаблон? Например, как в ansible? Конечно возможно! Сейчас покажу.
Источник: оригинал в Telegram
Давай возьмем огрызок конфига 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
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
Разбираем портянку. Логика простая, если hostname равен production, то присваиваем одни переменные. Во всех других случаях присваиваем другие переменные.
Далее вызываем функцию render и передаем в нее nginx_user и pid_path. Функция render всё это дело экспортирует в переменные окружения, а затем с помощью envsubst заменяет их в шаблоне. Готовый конфиг сразу попадает в папку с nginx. Охуенно! Кайф!
envsubst - заменяет переменную окружения новым значением в формате строки оболочки командной строки. Переменные могут быть заменены в формате ${var} или $var
Если у тебя много переменных, то можешь их разом экспортировать через цикл. В предыдущих постах у меня где-то есть примеры таких циклов.
Есть еще вариант с Heredoc. Heredoc-синтаксис — способ определения строковых переменных в исходном коде программ.
Пример скрипта, делает то же самое. Логику добавлять не стал:
#!/bin/bash
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
Отрендерится как нужно, но мне все же ближе вариант с envsubst. Нагляднее что ли. Выбор лишь за тобой, на каком велосипеде кататься. Вот такие пироги. Ладно, побежал я дальше работу работать. Будьте здоровы! Увидимся!








Комментарии