mirror of
https://github.com/kvz/bash3boilerplate.git
synced 2025-02-07 09:50:09 +00:00
243 lines
18 KiB
HTML
243 lines
18 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
|
||
<title>Faq | BASH3 Boilerplate – Template for writing better Bash scripts | BASH3 Boilerplate</title>
|
||
|
||
|
||
<meta name="keywords" content="bash, template, scripting, command-line">
|
||
<meta name="description" content="BASH3 Boilerplate">
|
||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700' rel='stylesheet' type='text/css'>
|
||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||
<link href="/assets/build/app.651a09ef8a9b4bbd05bb.css" rel="stylesheet">
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<div id="header-overlay"></div>
|
||
<a href="/">
|
||
<span id="logo"></span>
|
||
</a>
|
||
<div id="menu">
|
||
<i class="material-icons">menu</i>
|
||
<ul id="menu-items">
|
||
</ul>
|
||
</div>
|
||
<span id="more">
|
||
<i class="material-icons">expand_more</i>
|
||
</span>
|
||
</header>
|
||
<section id="content">
|
||
|
||
|
||
<h1 id="frequently-asked-questions">Frequently Asked Questions</h1>
|
||
|
||
<h2 id="what-is-a-cli">What is a CLI?</h2>
|
||
|
||
<p>A “CLI” is a <a href="https://en.wikipedia.org/wiki/Command-line_interface">command-line interface</a>.</p>
|
||
|
||
<h2 id="how-do-i-incorporate-bash3-boilerplate-into-my-own-project">How do I incorporate BASH3 Boilerplate into my own project?</h2>
|
||
|
||
<p>You can incorporate BASH3 Boilerplate into your project in one of two ways:</p>
|
||
|
||
<ol>
|
||
<li>Copy the desired portions of <a href="http://bash3boilerplate.sh/main.sh"><code class="language-plaintext highlighter-rouge">main.sh</code></a> into your own script.</li>
|
||
<li>Download <a href="http://bash3boilerplate.sh/main.sh"><code class="language-plaintext highlighter-rouge">main.sh</code></a> and start pressing the delete-key to remove unwanted things</li>
|
||
</ol>
|
||
|
||
<p>Once the <code class="language-plaintext highlighter-rouge">main.sh</code> has been tailor-made for your project, you can either append your own script in the same file, or source it in the following ways:</p>
|
||
|
||
<ol>
|
||
<li>Copy <a href="http://bash3boilerplate.sh/main.sh"><code class="language-plaintext highlighter-rouge">main.sh</code></a> into the same directory as your script and then edit and embed it into your script using Bash’s <code class="language-plaintext highlighter-rouge">source</code> include feature, e.g.:</li>
|
||
</ol>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
|
||
<span class="nb">source </span>main.sh
|
||
</code></pre></div></div>
|
||
|
||
<ol>
|
||
<li>Source <a href="http://bash3boilerplate.sh/main.sh"><code class="language-plaintext highlighter-rouge">main.sh</code></a> in your script or at the command line:</li>
|
||
</ol>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
|
||
<span class="nb">source </span>main.sh
|
||
</code></pre></div></div>
|
||
|
||
<h2 id="how-do-i-add-a-command-line-flag">How do I add a command-line flag?</h2>
|
||
|
||
<ol>
|
||
<li>Copy the line from the <code class="language-plaintext highlighter-rouge">main.sh</code> <a href="https://github.com/kvz/bash3boilerplate/blob/v2.1.0/main.sh#L109-L115">read block</a> that most resembles the desired behavior and paste the line into the same block.</li>
|
||
<li>Edit the single-character (e.g., <code class="language-plaintext highlighter-rouge">-d</code>) and, if present, the multi-character (e.g., <code class="language-plaintext highlighter-rouge">--debug</code>) versions of the flag in the copied line.</li>
|
||
<li>Omit the <code class="language-plaintext highlighter-rouge">[arg]</code> text in the copied line, if the desired flag takes no arguments.</li>
|
||
<li>Omit or edit the text after <code class="language-plaintext highlighter-rouge">Default=</code> to set or not set default values, respectively.</li>
|
||
<li>Omit the <code class="language-plaintext highlighter-rouge">Required.</code> text, if the flag is optional.</li>
|
||
</ol>
|
||
|
||
<h2 id="how-do-i-access-the-value-of-a-command-line-argument">How do I access the value of a command-line argument?</h2>
|
||
|
||
<p>To find out the value of an argument, append the corresponding single-character flag to the text <code class="language-plaintext highlighter-rouge">$arg_</code>. For example, if the [read block]
|
||
contains the line</p>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nt">-t</span> <span class="nt">--temp</span> <span class="o">[</span>arg] Location of tempfile. <span class="nv">Default</span><span class="o">=</span><span class="s2">"/tmp/bar"</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>then you can evaluate the corresponding argument and assign it to a variable as follows:</p>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">__temp_file_name</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">arg_t</span><span class="k">}</span><span class="s2">"</span>
|
||
</code></pre></div></div>
|
||
|
||
<h2 id="what-is-a-magic-variable">What is a magic variable?</h2>
|
||
|
||
<p>The <a href="https://github.com/kvz/bash3boilerplate/blob/v2.1.0/main.sh#L26-L28">magic variables</a> in <code class="language-plaintext highlighter-rouge">main.sh</code> are special in that they have a different value, depending on your environment. You can use <code class="language-plaintext highlighter-rouge">${__file}</code> to get a reference to your current script, and <code class="language-plaintext highlighter-rouge">${__dir}</code> to get a reference to the directory it lives in. This is not to be confused with the location of the calling script that might be sourcing the <code class="language-plaintext highlighter-rouge">${__file}</code>, which is accessible via <code class="language-plaintext highlighter-rouge">${0}</code>, or the current directory of the administrator running the script, accessible via <code class="language-plaintext highlighter-rouge">$(pwd)</code>.</p>
|
||
|
||
<h2 id="how-do-i-submit-an-issue-report">How do I submit an issue report?</h2>
|
||
|
||
<p>Please visit our <a href="https://github.com/kvz/bash3boilerplate/issues">Issues</a> page.</p>
|
||
|
||
<h2 id="how-can-i-contribute-to-this-project">How can I contribute to this project?</h2>
|
||
|
||
<p>Please fork this repository. After that, create a branch containing your suggested changes and submit a pull request based on the master branch
|
||
of <a href="https://github.com/kvz/bash3boilerplate/">https://github.com/kvz/bash3boilerplate/</a>. We are always more than happy to accept your contributions!</p>
|
||
|
||
<h2 id="why-are-you-typing-bash-in-all-caps">Why are you typing BASH in all caps?</h2>
|
||
|
||
<p>As an acronym, Bash stands for Bourne-again shell, and is usually written with one uppercase.
|
||
This project’s name, however, is “BASH3 Boilerplate”. It is a reference to
|
||
“<a href="https://html5boilerplate.com/">HTML5 Boilerplate</a>”, which was founded to serve a similar purpose,
|
||
only for crafting webpages.
|
||
Somewhat inconsistent – but true to Unix ancestry – the abbreviation for our project is “b3bp”.</p>
|
||
|
||
<h2 id="how-can-i-locally-develop-and-preview-the-b3bp-website">How can I locally develop and preview the b3bp website?</h2>
|
||
|
||
<p>You should have a working Node.js >=10, Ruby >=2 and <a href="https://yarnpkg.com">YARN</a> install on your workstation. When that is the case, you can run:</p>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yarn <span class="nb">install
|
||
</span>npm run start
|
||
</code></pre></div></div>
|
||
|
||
<p>This will install and start all required services and automatically open a webbrowser that reloads as soon as you make any changes to the source.</p>
|
||
|
||
<p>The source mainly consists of:</p>
|
||
|
||
<ul>
|
||
<li><code class="language-plaintext highlighter-rouge">./README.md</code> (Front page)</li>
|
||
<li><code class="language-plaintext highlighter-rouge">./FAQ.md</code> (FAQ page)</li>
|
||
<li><code class="language-plaintext highlighter-rouge">./CHANGELOG.md</code> (changelog page)</li>
|
||
<li><code class="language-plaintext highlighter-rouge">./website/_layouts/default.html</code> (the design in which all pages are rendered)</li>
|
||
<li><code class="language-plaintext highlighter-rouge">./website/assets/app.js</code> (main JS file)</li>
|
||
<li><code class="language-plaintext highlighter-rouge">./website/assets/style.css</code> (main CSS file)</li>
|
||
</ul>
|
||
|
||
<p>The rest is dark magic from which you should probably steer clear. : )</p>
|
||
|
||
<p>Any changes should be proposed as PRs. Anything added to <code class="language-plaintext highlighter-rouge">master</code> is automatically deployed using a combination of GitHub Actions and Pages.</p>
|
||
|
||
<h2 id="you-are-saying-you-are-portable-but-why-wont-b3bp-code-run-in-dash--busybox--posh--ksh--mksh--zsh">You are saying you are portable, but why won’t b3bp code run in dash / busybox / posh / ksh / mksh / zsh?</h2>
|
||
|
||
<p>When we say <em>portable</em>, we mean across Bash versions. Bash is widespread and most systems
|
||
offer at least version 3 of it. Make sure you have that available and b3bp will work for you.</p>
|
||
|
||
<p>We run automated tests to make sure that it will. Here is some proof for the following platforms:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://travis-ci.org/kvz/bash3boilerplate/jobs/109804166#L91-L94">Linux</a> <code class="language-plaintext highlighter-rouge">GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)</code></li>
|
||
<li><a href="https://travis-ci.org/kvz/bash3boilerplate/jobs/109804167#L2453-L2455">OSX</a> <code class="language-plaintext highlighter-rouge">GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)</code></li>
|
||
</ul>
|
||
|
||
<p>This portability, however, does not mean that we try to be compatible with
|
||
KornShell, Zsh, posh, yash, dash, or other shells. We allow syntax that would explode if
|
||
you pasted it in anything but Bash 3 and up.</p>
|
||
|
||
<h2 id="how-do-i-do-operating-system-detection">How do I do Operating System detection?</h2>
|
||
|
||
<p>We used to offer a magic <code class="language-plaintext highlighter-rouge">__os</code> variable, but we quickly <a href="https://github.com/kvz/bash3boilerplate/issues/38">discovered</a> that it would be hard
|
||
to create a satisfactory abstraction that is not only correct, but also covers enough use-cases,
|
||
while still having a relatively small footprint in <code class="language-plaintext highlighter-rouge">main.sh</code>.</p>
|
||
|
||
<p>For simple OS detection, we recommend using the <code class="language-plaintext highlighter-rouge">${OSTYPE}</code> variable available in Bash as
|
||
is demoed in <a href="http://stackoverflow.com/a/8597411/151666">this stackoverflow post</a>:</p>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">OSTYPE</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"linux-gnu"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
|
||
</span><span class="nb">echo</span> <span class="s2">"GNU Linux"</span>
|
||
<span class="k">elif</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">OSTYPE</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"darwin"</span><span class="k">*</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
|
||
</span><span class="nb">echo</span> <span class="s2">"Mac OSX"</span>
|
||
<span class="k">elif</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">OSTYPE</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"cygwin"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
|
||
</span><span class="nb">echo</span> <span class="s2">"POSIX compatibility layer and Linux environment emulation for Windows"</span>
|
||
<span class="k">elif</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">OSTYPE</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"msys"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
|
||
</span><span class="nb">echo</span> <span class="s2">"Lightweight shell and GNU utilities compiled for Windows (part of MinGW)"</span>
|
||
<span class="k">elif</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">OSTYPE</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"win32"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
|
||
</span><span class="nb">echo</span> <span class="s2">"I'm not sure this can happen."</span>
|
||
<span class="k">elif</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">OSTYPE</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"freebsd"</span><span class="k">*</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
|
||
</span><span class="nb">echo</span> <span class="s2">"..."</span>
|
||
<span class="k">else
|
||
</span><span class="nb">echo</span> <span class="s2">"Unknown."</span>
|
||
<span class="k">fi</span>
|
||
</code></pre></div></div>
|
||
|
||
<h2 id="how-do-i-access-a-potentially-unset-environment-variable">How do I access a potentially unset (environment) variable?</h2>
|
||
|
||
<p>The set -o nounset line in <code class="language-plaintext highlighter-rouge">main.sh</code> causes error termination when an unset environment variables is detected as unbound. There are multiple ways to avoid this.</p>
|
||
|
||
<p>Some code to illustrate:</p>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># method 1</span>
|
||
<span class="nb">echo</span> <span class="k">${</span><span class="nv">NAME1</span><span class="k">:-</span><span class="nv">Damian</span><span class="k">}</span> <span class="c"># echos Damian, $NAME1 is still unset</span>
|
||
<span class="c"># method 2</span>
|
||
<span class="nb">echo</span> <span class="k">${</span><span class="nv">NAME2</span>:<span class="p">=Damian</span><span class="k">}</span> <span class="c"># echos Damian, $NAME2 is set to Damian</span>
|
||
<span class="c"># method 3</span>
|
||
<span class="nv">NAME3</span><span class="o">=</span><span class="k">${</span><span class="nv">NAME3</span><span class="k">:-</span><span class="nv">Damian</span><span class="k">}</span><span class="p">;</span> <span class="nb">echo</span> <span class="k">${</span><span class="nv">NAME3</span><span class="k">}</span> <span class="c"># echos Damian, $NAME3 is set to Damian</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>This subject is briefly touched on as well in the <a href="README.md#safety-and-portability">Safety and Portability section under point 5</a>. b3bp currently uses <a href="https://github.com/kvz/bash3boilerplate/blob/v2.1.0/main.sh#L252">method 1</a> when we want to access a variable that could be undeclared, and <a href="https://github.com/kvz/bash3boilerplate/blob/v2.1.0/main.sh#L31">method 3</a> when we also want to set a default to an undeclared variable, because we feel it is more readable than method 2. We feel <code class="language-plaintext highlighter-rouge">:=</code> is easily overlooked, and not very beginner friendly. Method 3 seems more explicit in that regard in our humble opinion.</p>
|
||
|
||
<h2 id="how-can-i-detect-or-trap-ctrl-c-and-other-signals">How can I detect or trap Ctrl-C and other signals?</h2>
|
||
|
||
<p>You can trap <a href="https://en.wikipedia.org/wiki/Unix_signal">Unix signals</a> like <a href="https://en.wikipedia.org/wiki/Control-C">Ctrl-C</a> with code similar to:</p>
|
||
|
||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># trap ctrl-c and call ctrl_c()</span>
|
||
<span class="nb">trap </span>ctrl_c INT
|
||
|
||
<span class="k">function </span>ctrl_c<span class="o">()</span> <span class="o">{</span>
|
||
<span class="nb">echo</span> <span class="s2">"** Trapped CTRL-C"</span>
|
||
<span class="o">}</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>See http://mywiki.wooledge.org/SignalTrap for a list of signals, examples, and an in depth discussion.</p>
|
||
|
||
<h2 id="how-can-i-get-the-pid-of-my-running-script">How can I get the PID of my running script?</h2>
|
||
|
||
<p>The PID of a running script is contained in the <code class="language-plaintext highlighter-rouge">${$}</code> variable. This is <em>not</em> the pid of any subshells. With Bash 4 you can get the PID of your subshell with <code class="language-plaintext highlighter-rouge">${BASHPID}</code>. For a comprehensive list of Bash built in variables see, e.g., http://www.tldp.org/LDP/abs/html/internalvariables.html</p>
|
||
|
||
<p><a href="/">« Home</a></p>
|
||
|
||
|
||
|
||
|
||
<div class="Social">
|
||
<iframe src="http://ghbtns.com/github-btn.html?user=kvz&repo=bash3boilerplate&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="100" height="20"></iframe>
|
||
</div>
|
||
|
||
<p>
|
||
<small>
|
||
<hr />
|
||
Website design based on
|
||
the wonderful <a href="http://apex.run">apex.run</a>
|
||
with <a href="https://twitter.com/tjholowaychuk/status/744909762865696769">the author's consent</a>.
|
||
</small>
|
||
</p>
|
||
</section>
|
||
</body>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/languages/bash.min.js"></script>
|
||
<script src="/assets/build/app.d4d83e4b521b710b267c.js"></script>
|
||
<script>
|
||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||
|
||
ga('create', 'UA-63083-13', 'auto');
|
||
ga('send', 'pageview');
|
||
</script>
|
||
</html>
|