diff options
Diffstat (limited to 'stupid_templating_with_shell_cat_and_envsubst.html')
-rw-r--r-- | stupid_templating_with_shell_cat_and_envsubst.html | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/stupid_templating_with_shell_cat_and_envsubst.html b/stupid_templating_with_shell_cat_and_envsubst.html new file mode 100644 index 0000000..7a84554 --- /dev/null +++ b/stupid_templating_with_shell_cat_and_envsubst.html @@ -0,0 +1,72 @@ +<!doctype html> +<html lang="en"> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<meta name="author" content="aki"> +<meta name="tags" content="template, bash, cat, shell, envsubst"> +<link rel="icon" type="image/png" href="cylo.png"> +<link rel="stylesheet" type="text/css" href="style.css"> + +<title>Stupid Templating With Shell, cat and envsubst</title> + +<nav><p><a href="https://ignore.pl">ignore.pl</a></p></nav> + +<article> +<h1>Stupid Templating With Shell, cat and envsubst</h1> +<p class="subtitle">Published on 2020-07-14 20:26:00+02:00 +<p>Now something trivial and fun. Creating templates of documents or configurations in shell. There are two reasons why +I considered doing that instead of using some more verbose utilities. First off, availability - I have POSIX compliant +shell pretty much everywhere I go. It's a big part of my usual environment and because of that I'm used to it. That's +the second reason - frequency I use it with. It's good to mention that it's one of more verbose utilities out there. +<p>Let's start with plain shell. I actually use this method to serve the blog posts via fcgiwrap. I use it with a single +file, but it can accept external files. However those files won't have their content expanded in any way. If you keep it +in a one script file then it's possible. Basically, I'm talking about <code>cat</code>:</p> +<pre> +#!/bin/sh +cat /dev/fd/3 $@ /dev/fd/4 3<<BEFORE 4<<AFTER +<!doctype html> +<html lang="en"> +BEFORE +<script src=""></script> +AFTER +</pre> +<img src="stupid_templating_with_shell_cat_and_envsubst-1.png" alt="actual cat"> +<p>What you see here is a combination of +<a href="https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04">heredoc</a> and plain +redirection. It's done like this to avoid calling <code>cat</code> more than once. The script simply concatenates BEFORE +heredoc with any arguments passed to the script, and finally with AFTER heredoc. The output is similar to what you see +in source of this page. The template is trimmed for the sake of the example. +<p>Now, now. Heredoc can easily expand variables but if we were to <code>cat before.inl $@ after.inl</code> it wouldn't +work. For that I use +<code><a href="https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html">envsubst</a></code>. +Consider file called <i>template.conf</i>: +<pre> +server { + listen 80; + server_name $DOMAIN$ALIASES; + root /srv/http/$DOMAIN/public; +} +</pre> +<p>It could be wrapped in cat and heredoc, but for me it's not desired. Let's say I want my configuration templates to +be exactly that not executable scripts. There are three different solutions that I've heard: <code>eval</code>, +<code>sed</code> and <code>envsubst</code>. <code>Eval</code> can lead to dangerous situations and minor problems with +whitespace. <code>Sed</code> is what I believe is the most typical and straight-forward solution. As for the last one, +it goes like this:</p> +<pre> +$ export DOMAIN=example.tld +$ export ALIASES=' www.example.tld' +$ envsubst '$DOMAIN$ALIASES' <template.conf +server { + listen 80; + server_name example.tld www.example.tld; + root /srv/http/example.tld/public; +} +</pre> +<p>First, you set the variables (if they are not yet there). Then call the <code>envsubst</code> with a single variable +and redirect the template file into it. This single variable is called <em>SHELL-FORMAT</em>. It restricts the variables +that will be substituted in the input. It's completely optional, but if you have some <code>$server_name</code> you +don't want to substitute, then it's kind of useful. It actually doesn't have any format, you just need to reference the +variables in it: <code>'$DOMAIN$ALIASES'</code>, <code>'$DOMAIN $ALIASES'</code>, and <code>'$DOMAIN,$ALIASES'</code> +all work the same. +</article> +<script src="https://stats.ignore.pl/track.js"></script> |