<p>Delete-Key-<strong>Friendly</strong>. Instead of introducing packages, includes, compilers, etc., we propose using <ahref="http://bash3boilerplate.sh/main.sh"><codeclass="language-plaintext highlighter-rouge">main.sh</code></a> as a base and removing the parts you don’t need.
While this may feel a bit archaic at first, it is exactly the strength of Bash scripts that we should want to embrace.</p>
<p><strong>Portable</strong>. We are targeting Bash 3 (OSX still ships
with 3, for instance). If you are going to ask people to install
Bash 4 first, you might as well pick a more advanced language as a
dependency.</p>
<h2id="features">Features</h2>
<ul>
<li>Conventions that will make sure that all your scripts follow the same, battle-tested structure</li>
<li>Safe by default (break on error, pipefail, etc.)</li>
<li>Configuration by environment variables</li>
<li>Simple command-line argument parsing that requires no external dependencies. Definitions are parsed from help info, ensuring there will be no duplication</li>
<li>Helpful magic variables like <codeclass="language-plaintext highlighter-rouge">__file</code> and <codeclass="language-plaintext highlighter-rouge">__dir</code></li>
<li>Logging that supports colors and is compatible with <ahref="http://en.wikipedia.org/wiki/Syslog#Severity_levels">Syslog Severity levels</a>, as well as the <ahref="http://12factor.net/">twelve-factor</a> guidelines</li>
</ul>
<h2id="installation">Installation</h2>
<p>There are three different ways to install b3bp:</p>
<h3id="option-1-download-the-main-template">Option 1: Download the main template</h3>
<p>Use curl or wget to download the source and save it as your script. Then you can start deleting the unwanted bits, and adding your own logic.</p>
<p>Besides <codeclass="language-plaintext highlighter-rouge">main.sh</code>, this will also get you the entire b3bp repository. This includes a few extra functions that we keep in the <codeclass="language-plaintext highlighter-rouge">./src</code> directory.</p>
<p>As of <codeclass="language-plaintext highlighter-rouge">v1.0.3</code>, b3bp can also be installed as a Node module, meaning you can define it as a dependency in <codeclass="language-plaintext highlighter-rouge">package.json</code> via:</p>
<p>Even though this option introduces a Node.js dependency, it does allow for easy version pinning and distribution in environments that already have this prerequisite. This is, however, entirely optional and nothing prevents you from ignoring this possibility.</p>
<h2id="changelog">Changelog</h2>
<p>Please see the <ahref="./CHANGELOG.md">CHANGELOG.md</a> file.</p>
<p>As of <codeclass="language-plaintext highlighter-rouge">v1.0.3</code>, b3bp offers some nice re-usable libraries in <codeclass="language-plaintext highlighter-rouge">./src</code>. In order to make the snippets in <codeclass="language-plaintext highlighter-rouge">./src</code> more useful, we recommend the following guidelines.</p>
<p>It is nice to have a Bash package that can not only be used in the terminal, but also invoked as a command line function. In order to achieve this, the exporting of your functionality <em>should</em> follow this pattern:</p>
<li>In functions, use <codeclass="language-plaintext highlighter-rouge">local</code> before every variable declaration.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">UPPERCASE_VARS</code> to indicate environment variables that can be controlled outside your script.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">__double_underscore_prefixed_vars</code> to indicate global variables that are solely controlled inside your script, with the exception of arguments that are already prefixed with <codeclass="language-plaintext highlighter-rouge">arg_</code>, as well as functions, over which b3bp poses no restrictions.</li>
<li>Use long options (<codeclass="language-plaintext highlighter-rouge">logger --priority</code> vs <codeclass="language-plaintext highlighter-rouge">logger -p</code>). If you are on the CLI, abbreviations make sense for efficiency. Nevertheless, when you are writing reusable scripts, a few extra keystrokes will pay off in readability and avoid ventures into man pages in the future, either by you or your collaborators. Similarly, we prefer <codeclass="language-plaintext highlighter-rouge">set -o nounset</code> over <codeclass="language-plaintext highlighter-rouge">set -u</code>.</li>
<li>Use a single equal sign when checking <codeclass="language-plaintext highlighter-rouge">if [[ "${NAME}" = "Kevin" ]]</code>; double or triple signs are not needed.</li>
<li>Use the new bash builtin test operator (<codeclass="language-plaintext highlighter-rouge">[[ ... ]]</code>) rather than the old single square bracket test operator or explicit call to <codeclass="language-plaintext highlighter-rouge">test</code>.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">{}</code> to enclose your variables. Otherwise, Bash will try to access the <codeclass="language-plaintext highlighter-rouge">$ENVIRONMENT_app</code> variable in <codeclass="language-plaintext highlighter-rouge">/srv/$ENVIRONMENT_app</code>, whereas you probably intended <codeclass="language-plaintext highlighter-rouge">/srv/${ENVIRONMENT}_app</code>. Since it is easy to miss cases like this, we recommend that you make enclosing a habit.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">set</code>, rather than relying on a shebang like <codeclass="language-plaintext highlighter-rouge">#!/usr/bin/env bash -e</code>, since that is neutralized when someone runs your script as <codeclass="language-plaintext highlighter-rouge">bash yourscript.sh</code>.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">#!/usr/bin/env bash</code>, as it is more portable than <codeclass="language-plaintext highlighter-rouge">#!/bin/bash</code>.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">${BASH_SOURCE[0]}</code> if you refer to current file, even if it is sourced by a parent script. In other cases, use <codeclass="language-plaintext highlighter-rouge">${0}</code>.</li>
<li>Use <codeclass="language-plaintext highlighter-rouge">:-</code> if you want to test variables that could be undeclared. For instance, with <codeclass="language-plaintext highlighter-rouge">if [[ "${NAME:-}" = "Kevin" ]]</code>, <codeclass="language-plaintext highlighter-rouge">$NAME</code> will evaluate to <codeclass="language-plaintext highlighter-rouge">Kevin</code> if the variable is empty. The variable itself will remain unchanged. The syntax to assign a default value is <codeclass="language-plaintext highlighter-rouge">${NAME:=Kevin}</code>.</li>
<p>We are looking for endorsements! Are you also using b3bp? <ahref="https://github.com/kvz/bash3boilerplate/issues/new?title=I%20use%20b3bp">Let us know</a> and get listed.</p>
<h2id="authors">Authors</h2>
<ul>
<li><ahref="http://kvz.io">Kevin van Zonneveld</a></li>