Update website by travis

This commit is contained in:
lekevbot 2020-06-08 08:28:42 +00:00
commit 7fd386a584
37 changed files with 3550 additions and 0 deletions

11
CHANGELOG.md/index.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting&hellip;</title>
<link rel="canonical" href="/changelog/">
<script>location="/changelog/"</script>
<meta http-equiv="refresh" content="0; url=/changelog/">
<meta name="robots" content="noindex">
<h1>Redirecting&hellip;</h1>
<a href="/changelog/">Click here if you are not redirected.</a>
</html>

1
CNAME Normal file
View File

@ -0,0 +1 @@
bash3boilerplate.sh

11
FAQ.md/index.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting&hellip;</title>
<link rel="canonical" href="/faq/">
<script>location="/faq/"</script>
<meta http-equiv="refresh" content="0; url=/faq/">
<meta name="robots" content="noindex">
<h1>Redirecting&hellip;</h1>
<a href="/faq/">Click here if you are not redirected.</a>
</html>

1
README.md Normal file
View File

@ -0,0 +1 @@
This branch is just a deploy target. Do not edit. You changes will be lost.

13
assets/app.js Normal file
View File

@ -0,0 +1,13 @@
require('./main.js')
require('./style.css')
require('./syntax.css')
// check if HMR is enabled
if (module.hot) {
module.hot.accept('./main.js', function () {
require('./main.js');
});
module.hot.accept('./style.css', function () {
require('./style.css');
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="/assets/build/",n(n.s=0)}([function(e,n,t){e.exports=t(1)},function(e,n,t){"use strict";t(2),t(3),t(4)},function(e,n,t){"use strict";function r(){var e=document.getElementById("menu");Math.floor(.2*window.innerHeight)<window.pageYOffset+45?e.classList.remove("over-header"):e.classList.add("over-header")}var o=[1];hljs.initHighlighting();var i=window.sessionStorage,u=i.getItem("background");if(!u){u=o[Math.random()*o.length|0],console.log("setting background to %s",u),i.setItem("background",u)}document.getElementById("header-overlay").style.backgroundImage="url(/assets/images/"+u+".jpg)",document.addEventListener("DOMContentLoaded",r),window.onscroll=r;var c=function(e){return document.querySelector(e)}("#menu-items");(function(e){return Array.prototype.slice.call(document.querySelectorAll(e))})("#content h2").forEach(function(e){var n=document.createElement("li");n.innerHTML='<a href="#'+e.id+'">'+e.innerHTML+"</a>",c.appendChild(n)})},function(e,n){},function(e,n){}]);
//# sourceMappingURL=app.a6d50511e193d4224561.js.map

File diff suppressed because one or more lines are too long

208
assets/build/stats.html Normal file

File diff suppressed because one or more lines are too long

BIN
assets/images/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
assets/images/b3bp-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
assets/images/logo.pxm Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

File diff suppressed because one or more lines are too long

55
assets/main.js Normal file
View File

@ -0,0 +1,55 @@
// Backgrounds.
// var backgrounds = [1,2,3,4,5,6]
var backgrounds = [1]
// Highlighting.
hljs.initHighlighting()
// Storage.
var store = window.sessionStorage
// Background.
var background = store.getItem('background')
if (!background) {
var i = Math.random() * backgrounds.length | 0
background = backgrounds[i]
console.log('setting background to %s', background)
store.setItem('background', background)
}
// Body class for background.
var el = document.getElementById('header-overlay')
el.style.backgroundImage = 'url(/assets/images/' + background + '.jpg)'
// Attach class to #menu element depending on page offset.
document.addEventListener('DOMContentLoaded', chooseMenuColor)
window.onscroll = chooseMenuColor
function chooseMenuColor() {
var menuElement = document.getElementById('menu')
var menuTopOffset = 45
Math.floor(window.innerHeight * .20) < window.pageYOffset + menuTopOffset ?
menuElement.classList.remove('over-header') :
menuElement.classList.add('over-header')
}
function $get(selector) { return document.querySelector(selector) }
function $all(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
var container = $get('#menu-items')
// if (location.pathname !== '/') {
// var li = document.createElement('li');
// li.innerHTML = '<a href="/">&laquo; Home</a>';
// container.appendChild(li);
// }
$all('#content h2').forEach(function(el) {
var li = document.createElement('li');
li.innerHTML = '<a href="#' + el.id + '">' + el.innerHTML + '</a>';
container.appendChild(li);
})

345
assets/style.css Normal file
View File

@ -0,0 +1,345 @@
body {
font: 16px/1.625 "Open Sans", "Helvetica Neue", "Helvetica", Arial, sans-serif;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
color: #656a71;
margin: 0;
}
#header-overlay {
background: #131313 50% 100% no-repeat;
background-size: cover;
height: 20vh;
width: 100%;
opacity: 0;
-webkit-animation-name: overlay;
animation-name: overlay;
-webkit-animation-duration: 5s;
animation-duration: 5s;
-webkit-animation-delay: 1s;
animation-delay: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@-webkit-keyframes overlay {
0% {
opacity: 0;
}
100% {
opacity: .25;
}
}
@keyframes overlay {
0% {
opacity: 0;
}
100% {
opacity: .25;
}
}
body.background-1 #header-overlay {
background-image: url(images/1.jpg);
}
body.background-4 #header-overlay {
background-image: url(images/1.jpg);
}
#logo {
display: block;
background: url(images/b3bp-logo.png) center;
background-repeat: no-repeat;
background-size: contain;
width: 180px;
height: 120px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -60px;
-webkit-animation-name: logo;
animation-name: logo;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@-webkit-keyframes logo {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes logo {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#more {
position: absolute;
bottom: 10px;
left: 50%;
margin-left: -6px;
color: white;
opacity: 0;
-webkit-animation-name: move;
animation-name: move;
-webkit-animation-duration: 3s;
animation-duration: 3s;
-webkit-animation-delay: 3s;
animation-delay: 3s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1);
animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1);
}
@-webkit-keyframes move {
0% {
opacity: 0;
bottom: 300px;
}
50% {
opacity: 1;
bottom: 10px;
}
90% {
opacity: 1;
bottom: 10px;
}
100% {
opacity: 0;
bottom: -10px;
}
}
@keyframes move {
0% {
opacity: 0;
bottom: 300px;
}
50% {
opacity: 1;
bottom: 10px;
}
90% {
opacity: 1;
bottom: 10px;
}
100% {
opacity: 0;
bottom: -10px;
}
}
#content {
padding: 100px 0;
max-width: 650px;
margin: 0 auto;
}
#menu {
position: fixed;
top: 35px;
right: 35px;
cursor: pointer;
background: transparent;
color: black;
padding: 7px;
border-radius: 1px;
line-height: 0;
}
#menu.over-header {
color: white;
}
#menu i {
font-size: 19px;
}
#menu:hover #menu-items {
opacity: 1;
visibility: visible;
}
#menu-items {
line-height: 1.7;
opacity: 0;
position: fixed;
visibility: hidden;
margin: 0;
padding: 20px;
font-size: 12px;
background: white;
color: #121212;
top: 67px;
right: 35px;
border-radius: 1px;
text-align: right;
}
#menu-items li a:hover {
text-decoration: underline;
}
#menu-items li {
list-style: none;
}
#menu-items li a {
color: #4C4C4C;
}
h1, h2, h3, h4 {
font-weight: 600;
margin-bottom: 0px;
color: #3b444f;
}
h1 { font-size: 2em; /* 2*16 = 32 */ }
h2 { font-size: 1.5em; /* 1.5*16 = 24 */ }
h3 { font-size: 1.17em; /* 1.17*16 = 18.72 */ }
h4 { font-size: 1em; /* 1*16 = 16 */ }
h5 { font-size: 0.83em; /* 0.83*16 = 13.28 */ }
h6 { font-size: 0.75em; /* 0.75*16 = 12 */ }
h1 {
/*margin-top: 75px;*/
}
h1::before {
/*display: block;
content: ' ';
border-top: 1px dotted #eee;
width: 35%;
margin: 0 auto 75px auto;*/
}
h2 {
margin-top: 50px;
}
h3 {
margin-top: 30px;
}
p > code,
li > code {
border: 1px solid #eee;
padding: 2px 10px;
border-radius: 3px;
font-size: .75rem;
color: #555;
white-space: nowrap;
}
header {
background: #131313;
position: relative;
}
a {
text-decoration: none;
color: #55A1E1;
}
a:hover {
text-decoration: underline;
}
hr {
margin: 1px;
border: none;
height: 1px;
/* Set the hr color */
color: gainsboro; /* old IE */
background-color: gainsboro; /* Modern Browsers */
}
.Social {
margin: 0 auto;
text-align: center;
}
.Social > * {
display: inline;
margin: 0;
padding: 0;
}
.on-the-githubs {
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
}
.on-the-githubs:after {
content: '';
display: table;
clear: both;
}
.on-the-githubs > li {
list-style-type: none;
margin: 0;
padding: 0;
/*height: 26px;*/
position: relative;
border-bottom: 1px solid rgba(gainsboro, 0.3);
margin-bottom: 10px;
}
.on-the-githubs > li:after {
content: '';
display: table;
clear: both;
}
.on-the-githubs > li p {
font-size: 15px;
line-height: 16px;
margin: 0 2px;
padding: 0;
display: inline-block;
float: left;
overflow: hidden;
max-width: 80%;
}
.on-the-githubs > li abbr {
font-size: 12px;
line-height: 16px;
position: absolute;
right: 0;
float: left;
text-align: right;
/*display: none*/
}
.on-the-githubs > li a {
font-weight: normal;
/*text-decoration: underline;*/
}
.on-the-githubs > li img {
float: left;
margin: 0 2px 0 0;
border-radius: 10px;
width: 18px;
height: 18px;
}

104
assets/syntax.css Normal file
View File

@ -0,0 +1,104 @@
pre {
border-top-color: #ddd;
border-radius: 3px;
font-size: .75rem;
overflow-x: auto;
line-height: 1.3;
padding: 1.5rem;
background: #fff;
color: #333;
overflow-x: auto;
border: 1px solid #eee;
border-bottom-color: #ddd;
}
/*
XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>
*/
.hljs {
display: block;
}
.hljs-comment,
.hljs-quote {
color: #006a00;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal {
color: #aa0d91;
}
.hljs-name {
color: #008;
}
.hljs-variable,
.hljs-template-variable {
color: #660;
}
.hljs-string {
color: #c41a16;
}
.hljs-regexp,
.hljs-link {
color: #080;
}
.hljs-title,
.hljs-tag,
.hljs-symbol,
.hljs-bullet,
.hljs-number,
.hljs-meta {
color: #1c00cf;
}
.hljs-section,
.hljs-class .hljs-title,
.hljs-type,
.hljs-attr,
.hljs-built_in,
.hljs-builtin-name,
.hljs-params {
color: #5c2699;
}
.hljs-attribute,
.hljs-subst {
color: #000;
}
.hljs-formula {
background-color: #eee;
font-style: italic;
}
.hljs-addition {
background-color: #baeeba;
}
.hljs-deletion {
background-color: #ffc8bd;
}
.hljs-selector-id,
.hljs-selector-class {
color: #9b703f;
}
.hljs-doctag,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

252
changelog/index.html Normal file
View File

@ -0,0 +1,252 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Changelog | 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 rel="stylesheet" href="/assets/build/app.a6d50511e193d4224561.css" media="screen" charset="utf-8">
</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="changelog">Changelog</h1>
<p>Heres is a combined todo/done list. You can see what todos are planned for the upcoming release, as well as ideas that may/may not make into a release in <code class="highlighter-rouge">Ideas</code>.</p>
<h2 id="ideas">Ideas</h2>
<p>Unplanned.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Better style guide checking (#84)</li>
</ul>
<h2 id="master">master</h2>
<p>Released: TBA.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.4.2...master">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add feature to edit/update comments in ini file (#132, @rfuehrer)</li>
</ul>
<h2 id="v242">v2.4.2</h2>
<p>Released: 2019-11-07.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.4.1...v2.4.2">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Upgrade to <code class="highlighter-rouge">lanyon@0.1.16</code></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Capture correct error_code in err_report (#124, @eval)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Enhanced ini file handling: create new file, create new sections, handle default section, read key from given section (@rfuehrer)</li>
</ul>
<h2 id="v241">v2.4.1</h2>
<p>Released: 2019-11-07.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.3.0...v2.4.1">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Upgrade to <code class="highlighter-rouge">lanyon@0.1.7</code></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Allow counting how many times an argument is used (@genesiscloud)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix typos in megamount (thanks @gsaponaro)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Enable color in screen or tmux (#92, @gmasse)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Change <code class="highlighter-rouge">egrep</code> to <code class="highlighter-rouge">grep -E</code> in test and lib scripts to comply with ShellCheck (#92, @gmasse)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix typo in FAQ (#92, @gmasse)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix Travis CI failure on src/templater.sh (@gmasse)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add magic variable which contains full command invocation</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />More contrasted alert and emergency colors (#111 @gmeral)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add support for repeatable arguments (@genesiscloud)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix remaining warnings with shellcheck v0.7.0 (#107, @genesiscloud)</li>
</ul>
<h2 id="v240">v2.4.0</h2>
<p>Released: 2016-12-21.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.3.0...v2.4.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Upgrade to <code class="highlighter-rouge">lanyon@0.0.143</code></li>
</ul>
<h2 id="v230">v2.3.0</h2>
<p>Released: 2016-12-21.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.2.0...v2.3.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add magic variable <code class="highlighter-rouge">__i_am_main_script</code> to distinguish if b3bp is being sourced or called directly (#45, @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add style checks for tab characters and trailing whitespace (@zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add backtracing to help localize errors (#44, @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Additional FAQ entries (#47, suggested by @gdevenyi, implemented by @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Ensure that shifting over <code class="highlighter-rouge">--</code> doesnt throw an errexit error (#21, @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add Pull Request template (#83)</li>
</ul>
<h2 id="v220">v2.2.0</h2>
<p>Released: 2016-12-21.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.1.0...v2.2.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />README and FAQ improvements (#66, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add support for sourcing b3bp (#61, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Upgrade all Node.js dependencies for development (#78)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Switch to http://lanyon.io for static site building, add a new logo</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Cleanup environment variables (#58, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Support multi-line logs (#57, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Run shellcheck as part of the acceptance test (#79, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Brace all variables, used <code class="highlighter-rouge">[[</code> instead of <code class="highlighter-rouge">[</code> (#33, #76, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add automatic usage validation for required args (#22, #65, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Remove all usage of eval (@mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Get rid of awk, sed &amp; egrep usage (#71, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix auto-color-off code (#69, #70, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Use shellcheck to find and fix unclean code (#68, #80, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Allow for multiline opt description in <code class="highlighter-rouge">__usage</code> (#7, @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Allow <code class="highlighter-rouge">__usage</code> and <code class="highlighter-rouge">__helptext</code> to be defined before sourcing <code class="highlighter-rouge">main.sh</code> thus makeing b3bp behave like a library (@mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add the same License text to each script header (@mstreuhofer)</li>
</ul>
<h2 id="v210">v2.1.0</h2>
<p>Released: 2016-11-08.
<a href="https://github.com/kvz/bash3boilerplate/compare/v2.0.0...v2.1.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Cleanup b3bp variables (adds prefixes across the board) (thanks @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add multi-line logging support (thanks @mstreuhofer)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Mangle long-option names to allow dashes (thanks @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Remove OS detection altogether (#38, thx @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Offer the main template for download as http://bash3boilerplate.sh/main.sh</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Better OS detection (#38, thx @moviuro)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Improve README copy (#34, thx galaktos)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix unquoted variable access within (#34 thx galaktos)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />For delete-key-friendliness, bundle the commandline definition block along with its parser</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Less verbose header comments</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />For delete-key-friendliness, dont crash on undeclared help vars</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Introduce <code class="highlighter-rouge">errtrace</code>, which is on by default (BREAKING)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add a configurable <code class="highlighter-rouge">helptext</code> that is left alone by the parses and allows you to have a richer help</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add a simple documentation website</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add best practice of using <code class="highlighter-rouge">__double_underscore_prefixed_vars</code> to indicate global variables that are solely controlled inside your script</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Make license more permissive by not requiring distribution of the LICENSE file if the copyright &amp; attribution comments are left intact</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Respect <code class="highlighter-rouge">--no-color</code> by setting the <code class="highlighter-rouge">NO_COLOR</code> flag in <code class="highlighter-rouge">main.sh</code> (#25, thx @gdevenyi)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Split out changelog into separate file</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Added a <a href="./FAQ.md">FAQ</a> (#15, #14, thanks @rouson)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix Travis OSX testing (before, it would silently pass failures) (#10)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Enable dashes in long, GNU style options, as well as numbers (thanks @zbeekman)</li>
</ul>
<h2 id="v200">v2.0.0</h2>
<p>Released: 2016-02-17.
<a href="https://github.com/kvz/bash3boilerplate/compare/v1.2.1...v2.0.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add tests for <code class="highlighter-rouge">templater</code> and follow Library export best practices</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add tests for <code class="highlighter-rouge">ini_val</code> and follow Library export best practices</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add tests for <code class="highlighter-rouge">parse_url</code> and follow Library export best practices</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add tests for <code class="highlighter-rouge">megamount</code> and follow Library export best practices</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Remove <code class="highlighter-rouge">bump</code> from <code class="highlighter-rouge">src</code> (BREAKING)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Remove <code class="highlighter-rouge">semver</code> from <code class="highlighter-rouge">src</code> (BREAKING)</li>
</ul>
<h2 id="v121">v1.2.1</h2>
<p>Released: 2016-02-17.
<a href="https://github.com/kvz/bash3boilerplate/compare/v1.2.0...v1.2.1">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add Travis CI automated testing for OSX (thanks @zbeekman)</li>
</ul>
<h2 id="v120">v1.2.0</h2>
<p>Released: 2016-02-16.
<a href="https://github.com/kvz/bash3boilerplate/compare/v1.1.0...v1.2.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Allow disabling colors via <code class="highlighter-rouge">NO_COLOR</code> environment variable</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Enable <code class="highlighter-rouge">errexit</code>, <code class="highlighter-rouge">nounset</code> and <code class="highlighter-rouge">pipefail</code> options at the top of the script already</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />More refined colors (thanks @arathai)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add a changelog to the README</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add <code class="highlighter-rouge">__os</code> magic var (limited to discovering OSX and defaulting to Linux for now)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add <code class="highlighter-rouge">__base</code> magic var (<code class="highlighter-rouge">main</code>, if the source script is <code class="highlighter-rouge">main.sh</code>)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Enable long, GNU style options (thanks @zbeekman)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add Travis CI automated testing for Linux</li>
</ul>
<h2 id="v110">v1.1.0</h2>
<p>Released: 2015-06-29.
<a href="https://github.com/kvz/bash3boilerplate/compare/v1.0.3...v1.1.0">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add <code class="highlighter-rouge">ALLOW_REMAINDERS</code> configuration to templater</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Fix typo: debugmdoe to debugmode (thanks @jokajak)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Use <code class="highlighter-rouge">${BASH_SOURCE[0]}</code> for <code class="highlighter-rouge">__file</code> instead of <code class="highlighter-rouge">${0}</code></li>
</ul>
<h2 id="v103">v1.0.3</h2>
<p>Released: 2014-11-02.
<a href="https://github.com/kvz/bash3boilerplate/compare/5db569125319a89b9561b434db84e4d91faefb63...v1.0.3">Diff</a>.</p>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add <code class="highlighter-rouge">ini_val</code>, <code class="highlighter-rouge">megamount</code>, <code class="highlighter-rouge">parse_url</code></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Add re-usable libraries in <code class="highlighter-rouge">./src</code></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Use npm as an additional distribution channel</li>
</ul>
<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 async src="/assets/build/app.a6d50511e193d4224561.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>

242
faq/index.html Normal file
View File

@ -0,0 +1,242 @@
<!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 rel="stylesheet" href="/assets/build/app.a6d50511e193d4224561.css" media="screen" charset="utf-8">
</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="highlighter-rouge">main.sh</code></a> into your own script.</li>
<li>Download <a href="http://bash3boilerplate.sh/main.sh"><code class="highlighter-rouge">main.sh</code></a> and start pressing the delete-key to remove unwanted things</li>
</ol>
<p>Once the <code class="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="highlighter-rouge">main.sh</code></a> into the same directory as your script and then edit and embed it into your script using Bashs <code class="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="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="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="highlighter-rouge">-d</code>) and, if present, the multi-character (e.g., <code class="highlighter-rouge">--debug</code>) versions of the flag in the copied line.</li>
<li>Omit the <code class="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="highlighter-rouge">Default=</code> to set or not set default values, respectively.</li>
<li>Omit the <code class="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="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="highlighter-rouge">main.sh</code> are special in that they have a different value, depending on your environment. You can use <code class="highlighter-rouge">${__file}</code> to get a reference to your current script, and <code class="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="highlighter-rouge">${__file}</code>, which is accessible via <code class="highlighter-rouge">${0}</code>, or the current directory of the administrator running the script, accessible via <code class="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 projects 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 &gt;=10, Ruby &gt;=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="highlighter-rouge">./README.md</code> (Front page)</li>
<li><code class="highlighter-rouge">./FAQ.md</code> (FAQ page)</li>
<li><code class="highlighter-rouge">./CHANGELOG.md</code> (changelog page)</li>
<li><code class="highlighter-rouge">./website/_layouts/default.html</code> (the design in which all pages are rendered)</li>
<li><code class="highlighter-rouge">./website/assets/app.js</code> (main JS file)</li>
<li><code class="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="highlighter-rouge">master</code> is automatically deployed using a combination of Travis CI and GitHub 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 wont 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="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="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="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="highlighter-rouge">main.sh</code>.</p>
<p>For simple OS detection, we recommend using the <code class="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="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="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="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="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 async src="/assets/build/app.a6d50511e193d4224561.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>

248
index.html Normal file
View File

@ -0,0 +1,248 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BASH3 Boilerplate Template for writing better Bash scripts</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 rel="stylesheet" href="/assets/build/app.a6d50511e193d4224561.css" media="screen" charset="utf-8">
</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">
<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>
<a href="https://travis-ci.org/kvz/bash3boilerplate"><img src="https://travis-ci.org/kvz/bash3boilerplate.svg" alt="Build Status"></a>
</div>
<p>When hacking up Bash scripts, there are often things such as logging or command-line argument parsing that:</p>
<ul>
<li>You need every time</li>
<li>Come with a number of pitfalls you want to avoid</li>
<li>Keep you from your actual work</li>
</ul>
<p>Heres an attempt to bundle those things in a generalized way so that
they are reusable as-is in most scripts.</p>
<p>We call it “BASH3 Boilerplate” or b3bp for short.</p>
<h2 id="goals">Goals</h2>
<p>Delete-Key-<strong>Friendly</strong>. Instead of introducing packages, includes, compilers, etc., we propose using <a href="http://bash3boilerplate.sh/main.sh"><code class="highlighter-rouge">main.sh</code></a> as a base and removing the parts you dont 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>
<h2 id="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 <code class="highlighter-rouge">__file</code> and <code class="highlighter-rouge">__dir</code></li>
<li>Logging that supports colors and is compatible with <a href="http://en.wikipedia.org/wiki/Syslog#Severity_levels">Syslog Severity levels</a>, as well as the <a href="http://12factor.net/">twelve-factor</a> guidelines</li>
</ul>
<h2 id="installation">Installation</h2>
<p>There are three different ways to install b3bp:</p>
<h3 id="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>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget http://bash3boilerplate.sh/main.sh
vim main.sh
</code></pre></div></div>
<h3 id="option-2-clone-the-entire-project">Option 2: Clone the entire project</h3>
<p>Besides <code class="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 <code class="highlighter-rouge">./src</code> directory.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone git@github.com:kvz/bash3boilerplate.git
</code></pre></div></div>
<h3 id="option-3-require-via-npm">Option 3: Require via npm</h3>
<p>As of <code class="highlighter-rouge">v1.0.3</code>, b3bp can also be installed as a Node module, meaning you can define it as a dependency in <code class="highlighter-rouge">package.json</code> via:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm init
npm <span class="nb">install</span> <span class="nt">--save</span> <span class="nt">--save-exact</span> bash3boilerplate
</code></pre></div></div>
<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>
<h2 id="changelog">Changelog</h2>
<p>Please see the <a href="./CHANGELOG.md">CHANGELOG.md</a> file.</p>
<h2 id="frequently-asked-questions">Frequently Asked Questions</h2>
<p>Please see the <a href="./FAQ.md">FAQ.md</a> file.</p>
<h2 id="best-practices">Best practices</h2>
<p>As of <code class="highlighter-rouge">v1.0.3</code>, b3bp offers some nice re-usable libraries in <code class="highlighter-rouge">./src</code>. In order to make the snippets in <code class="highlighter-rouge">./src</code> more useful, we recommend the following guidelines.</p>
<h3 id="function-packaging">Function packaging</h3>
<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>
<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">BASH_SOURCE</span><span class="p">[0]</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"</span><span class="k">${</span><span class="nv">0</span><span class="k">}</span><span class="s2">"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
</span>my_script <span class="s2">"</span><span class="k">${</span><span class="p">@</span><span class="k">}</span><span class="s2">"</span>
<span class="nb">exit</span> <span class="nv">$?</span>
<span class="k">fi
</span><span class="nb">export</span> <span class="nt">-f</span> my_script
</code></pre></div></div>
<p>This allows a user to <code class="highlighter-rouge">source</code> your script or invoke it as a script.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Running as a script</span>
<span class="nv">$ </span>./my_script.sh some args <span class="nt">--blah</span>
<span class="c"># Sourcing the script</span>
<span class="nv">$ </span><span class="nb">source </span>my_script.sh
<span class="nv">$ </span>my_script some more args <span class="nt">--blah</span>
</code></pre></div></div>
<p>(taken from the <a href="https://raw.githubusercontent.com/bpkg/bpkg/master/README.md">bpkg</a> project)</p>
<h3 id="scoping">Scoping</h3>
<ol>
<li>In functions, use <code class="highlighter-rouge">local</code> before every variable declaration.</li>
<li>Use <code class="highlighter-rouge">UPPERCASE_VARS</code> to indicate environment variables that can be controlled outside your script.</li>
<li>Use <code class="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 <code class="highlighter-rouge">arg_</code>, as well as functions, over which b3bp poses no restrictions.</li>
</ol>
<h3 id="coding-style">Coding style</h3>
<ol>
<li>Use two spaces for tabs, do not use tab characters.</li>
<li>Do not introduce whitespace at the end of lines or on blank lines as they obfuscate version control diffs.</li>
<li>Use long options (<code class="highlighter-rouge">logger --priority</code> vs <code class="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 <code class="highlighter-rouge">set -o nounset</code> over <code class="highlighter-rouge">set -u</code>.</li>
<li>Use a single equal sign when checking <code class="highlighter-rouge">if [[ "${NAME}" = "Kevin" ]]</code>; double or triple signs are not needed.</li>
<li>Use the new bash builtin test operator (<code class="highlighter-rouge">[[ ... ]]</code>) rather than the old single square bracket test operator or explicit call to <code class="highlighter-rouge">test</code>.</li>
</ol>
<h3 id="safety-and-portability">Safety and Portability</h3>
<ol>
<li>Use <code class="highlighter-rouge">{}</code> to enclose your variables. Otherwise, Bash will try to access the <code class="highlighter-rouge">$ENVIRONMENT_app</code> variable in <code class="highlighter-rouge">/srv/$ENVIRONMENT_app</code>, whereas you probably intended <code class="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 <code class="highlighter-rouge">set</code>, rather than relying on a shebang like <code class="highlighter-rouge"><span class="c">#!/usr/bin/env bash -e</span></code>, since that is neutralized when someone runs your script as <code class="highlighter-rouge">bash yourscript.sh</code>.</li>
<li>Use <code class="highlighter-rouge"><span class="c">#!/usr/bin/env bash</span></code>, as it is more portable than <code class="highlighter-rouge"><span class="c">#!/bin/bash</span></code>.</li>
<li>Use <code class="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 <code class="highlighter-rouge">${0}</code>.</li>
<li>Use <code class="highlighter-rouge">:-</code> if you want to test variables that could be undeclared. For instance, with <code class="highlighter-rouge">if [[ "${NAME:-}" = "Kevin" ]]</code>, <code class="highlighter-rouge">$NAME</code> will evaluate to <code class="highlighter-rouge">Kevin</code> if the variable is empty. The variable itself will remain unchanged. The syntax to assign a default value is <code class="highlighter-rouge">${NAME:=Kevin}</code>.</li>
</ol>
<h2 id="who-uses-b3bp">Who uses b3bp?</h2>
<ul>
<li><a href="https://transloadit.com">Transloadit</a></li>
<li><a href="http://www.opencoarrays.org">OpenCoarrays</a></li>
<li><a href="http://www.sourceryinstitute.org">Sourcery Institute</a></li>
<li><a href="http://cobralab.ca/">Computational Brain Anatomy Laboratory</a></li>
<li><a href="https://genesiscloud.com/">Genesis Cloud</a></li>
</ul>
<p>We are looking for endorsements! Are you also using b3bp? <a href="https://github.com/kvz/bash3boilerplate/issues/new?title=I%20use%20b3bp">Let us know</a> and get listed.</p>
<h2 id="authors">Authors</h2>
<ul>
<li><a href="http://kvz.io">Kevin van Zonneveld</a></li>
<li><a href="https://izaakbeekman.com/">Izaak Beekman</a></li>
<li><a href="https://github.com/mstreuhofer">Manuel Streuhofer</a></li>
<li><a href="mailto:Alexander.Rathai@gmail.com">Alexander Rathai</a></li>
<li><a href="http://www.sourceryinstitute.org/">Dr. Damian Rouson</a> (documentation, feedback)</li>
<li><a href="https://github.com/jokajak">@jokajak</a> (documentation)</li>
<li><a href="http://staticwave.ca/">Gabriel A. Devenyi</a> (feedback)</li>
<li><a href="https://github.com/bravo-kernel">@bravo-kernel</a> (feedback)</li>
<li><a href="https://github.com/skanga">@skanga</a> (feedback)</li>
<li><a href="https://www.reddit.com/user/galaktos">galaktos</a> (feedback)</li>
<li><a href="https://github.com/moviuro">@moviuro</a> (feedback)</li>
<li><a href="https://github.com/gsaponaro">Giovanni Saponaro</a> (feedback)</li>
<li><a href="https://github.com/gmasse">Germain Masse</a></li>
<li><a href="https://github.com/warpengineer">A. G. Madi</a></li>
<li><a href="mailto:oss@genesiscloud.com">Lukas Stockner</a></li>
<li><a href="https://github.com/eval">Gert Goet</a></li>
<li><a href="https://github.com/rfuehrer">@rfuehrer</a></li>
</ul>
<h2 id="license">License</h2>
<p>Copyright (c) 2013 Kevin van Zonneveld and <a href="https://github.com/kvz/bash3boilerplate#authors">contributors</a>.
Licensed under <a href="https://raw.githubusercontent.com/kvz/bash3boilerplate/master/LICENSE">MIT</a>.
You are not obligated to bundle the LICENSE file with your b3bp projects as long
as you leave these references intact in the header comments of your source files.</p>
<h2 id="activity-feed">On GitHub</h2>
<p>
BASH3 Boilerplate is a friendly group of folks further developing our
re-usable templates as we go.
We'd love to hear what you think <a href="https://github.com/kvz/bash3boilerplate">on GitHub</a>.
Here's what's been going on recently.
</p>
<div class="on-the-githubs" data-event-source="repos/kvz/bash3boilerplate">Loading...</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//kvz.github.io/on-the-githubs/js/jquery.on-the-githubs.min.js"></script>
<script type="text/javascript">
$('.on-the-githubs').onthegithubs();
</script>
<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 async src="/assets/build/app.a6d50511e193d4224561.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>

452
main.sh Executable file
View File

@ -0,0 +1,452 @@
#!/usr/bin/env bash
# This file:
#
# - Demos BASH3 Boilerplate (change this for your script)
#
# Usage:
#
# LOG_LEVEL=7 ./main.sh -f /tmp/x -d (change this for your script)
#
# Based on a template by BASH3 Boilerplate v2.4.1
# http://bash3boilerplate.sh/#authors
#
# The MIT License (MIT)
# Copyright (c) 2013 Kevin van Zonneveld and contributors
# You are not obligated to bundle the LICENSE file with your b3bp projects as long
# as you leave these references intact in the header comments of your source files.
# Exit on error. Append "|| true" if you expect an error.
set -o errexit
# Exit on error inside any functions or subshells.
set -o errtrace
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
set -o nounset
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
set -o pipefail
# Turn on traces, useful while debugging but commented out by default
# set -o xtrace
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
__i_am_main_script="0" # false
if [[ "${__usage+x}" ]]; then
if [[ "${BASH_SOURCE[1]}" = "${0}" ]]; then
__i_am_main_script="1" # true
fi
__b3bp_external_usage="true"
__b3bp_tmp_source_idx=1
fi
else
__i_am_main_script="1" # true
[[ "${__usage+x}" ]] && unset -v __usage
[[ "${__helptext+x}" ]] && unset -v __helptext
fi
# Set magic variables for current file, directory, os, etc.
__dir="$(cd "$(dirname "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")"
__base="$(basename "${__file}" .sh)"
# shellcheck disable=SC2034,SC2015
__invocation="$(printf %q "${__file}")$( (($#)) && printf ' %q' "$@" || true)"
# Define the environment variables (and their defaults) that this script depends on
LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency
NO_COLOR="${NO_COLOR:-}" # true = disable color. otherwise autodetected
### Functions
##############################################################################
function __b3bp_log () {
local log_level="${1}"
shift
# shellcheck disable=SC2034
local color_debug="\\x1b[35m"
# shellcheck disable=SC2034
local color_info="\\x1b[32m"
# shellcheck disable=SC2034
local color_notice="\\x1b[34m"
# shellcheck disable=SC2034
local color_warning="\\x1b[33m"
# shellcheck disable=SC2034
local color_error="\\x1b[31m"
# shellcheck disable=SC2034
local color_critical="\\x1b[1;31m"
# shellcheck disable=SC2034
local color_alert="\\x1b[1;37;41m"
# shellcheck disable=SC2034
local color_emergency="\\x1b[1;4;5;37;41m"
local colorvar="color_${log_level}"
local color="${!colorvar:-${color_error}}"
local color_reset="\\x1b[0m"
if [[ "${NO_COLOR:-}" = "true" ]] || { [[ "${TERM:-}" != "xterm"* ]] && [[ "${TERM:-}" != "screen"* ]]; } || [[ ! -t 2 ]]; then
if [[ "${NO_COLOR:-}" != "false" ]]; then
# Don't use colors on pipes or non-recognized terminals
color=""; color_reset=""
fi
fi
# all remaining arguments are to be printed
local log_line=""
while IFS=$'\n' read -r log_line; do
echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%9s]" "${log_level}")${color_reset} ${log_line}" 1>&2
done <<< "${@:-}"
}
function emergency () { __b3bp_log emergency "${@}"; exit 1; }
function alert () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && __b3bp_log alert "${@}"; true; }
function critical () { [[ "${LOG_LEVEL:-0}" -ge 2 ]] && __b3bp_log critical "${@}"; true; }
function error () { [[ "${LOG_LEVEL:-0}" -ge 3 ]] && __b3bp_log error "${@}"; true; }
function warning () { [[ "${LOG_LEVEL:-0}" -ge 4 ]] && __b3bp_log warning "${@}"; true; }
function notice () { [[ "${LOG_LEVEL:-0}" -ge 5 ]] && __b3bp_log notice "${@}"; true; }
function info () { [[ "${LOG_LEVEL:-0}" -ge 6 ]] && __b3bp_log info "${@}"; true; }
function debug () { [[ "${LOG_LEVEL:-0}" -ge 7 ]] && __b3bp_log debug "${@}"; true; }
function help () {
echo "" 1>&2
echo " ${*}" 1>&2
echo "" 1>&2
echo " ${__usage:-No usage available}" 1>&2
echo "" 1>&2
if [[ "${__helptext:-}" ]]; then
echo " ${__helptext}" 1>&2
echo "" 1>&2
fi
exit 1
}
### Parse commandline options
##############################################################################
# Commandline options. This defines the usage page, and is used to parse cli
# opts & defaults from. The parsing is unforgiving so be precise in your syntax
# - A short option must be preset for every long option; but every short option
# need not have a long option
# - `--` is respected as the separator between options and arguments
# - We do not bash-expand defaults, so setting '~/app' as a default will not resolve to ${HOME}.
# you can use bash variables to work around this (so use ${HOME} instead)
# shellcheck disable=SC2015
[[ "${__usage+x}" ]] || read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered
-f --file [arg] Filename to process. Required.
-t --temp [arg] Location of tempfile. Default="/tmp/bar"
-v Enable verbose mode, print script as it is executed
-d --debug Enables debug mode
-h --help This page
-n --no-color Disable color output
-1 --one Do just one thing
-i --input [arg] File to process. Can be repeated.
-x Specify a flag. Can be repeated.
EOF
# shellcheck disable=SC2015
[[ "${__helptext+x}" ]] || read -r -d '' __helptext <<-'EOF' || true # exits non-zero when EOF encountered
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
EOF
# Translate usage string -> getopts arguments, and set $arg_<flag> defaults
while read -r __b3bp_tmp_line; do
if [[ "${__b3bp_tmp_line}" =~ ^- ]]; then
# fetch single character version of option string
__b3bp_tmp_opt="${__b3bp_tmp_line%% *}"
__b3bp_tmp_opt="${__b3bp_tmp_opt:1}"
# fetch long version if present
__b3bp_tmp_long_opt=""
if [[ "${__b3bp_tmp_line}" = *"--"* ]]; then
__b3bp_tmp_long_opt="${__b3bp_tmp_line#*--}"
__b3bp_tmp_long_opt="${__b3bp_tmp_long_opt%% *}"
fi
# map opt long name to+from opt short name
printf -v "__b3bp_tmp_opt_long2short_${__b3bp_tmp_long_opt//-/_}" '%s' "${__b3bp_tmp_opt}"
printf -v "__b3bp_tmp_opt_short2long_${__b3bp_tmp_opt}" '%s' "${__b3bp_tmp_long_opt//-/_}"
# check if option takes an argument
if [[ "${__b3bp_tmp_line}" =~ \[.*\] ]]; then
__b3bp_tmp_opt="${__b3bp_tmp_opt}:" # add : if opt has arg
__b3bp_tmp_init="" # it has an arg. init with ""
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "1"
elif [[ "${__b3bp_tmp_line}" =~ \{.*\} ]]; then
__b3bp_tmp_opt="${__b3bp_tmp_opt}:" # add : if opt has arg
__b3bp_tmp_init="" # it has an arg. init with ""
# remember that this option requires an argument
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "2"
else
__b3bp_tmp_init="0" # it's a flag. init with 0
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "0"
fi
__b3bp_tmp_opts="${__b3bp_tmp_opts:-}${__b3bp_tmp_opt}"
if [[ "${__b3bp_tmp_line}" =~ ^Can\ be\ repeated\. ]] || [[ "${__b3bp_tmp_line}" =~ \.\ *Can\ be\ repeated\. ]]; then
# remember that this option can be repeated
printf -v "__b3bp_tmp_is_array_${__b3bp_tmp_opt:0:1}" '%s' "1"
else
printf -v "__b3bp_tmp_is_array_${__b3bp_tmp_opt:0:1}" '%s' "0"
fi
fi
[[ "${__b3bp_tmp_opt:-}" ]] || continue
if [[ "${__b3bp_tmp_line}" =~ ^Default= ]] || [[ "${__b3bp_tmp_line}" =~ \.\ *Default= ]]; then
# ignore default value if option does not have an argument
__b3bp_tmp_varname="__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}"
if [[ "${!__b3bp_tmp_varname}" != "0" ]]; then
# take default
__b3bp_tmp_init="${__b3bp_tmp_line##*Default=}"
# strip double quotes from default argument
__b3bp_tmp_re='^"(.*)"$'
if [[ "${__b3bp_tmp_init}" =~ ${__b3bp_tmp_re} ]]; then
__b3bp_tmp_init="${BASH_REMATCH[1]}"
else
# strip single quotes from default argument
__b3bp_tmp_re="^'(.*)'$"
if [[ "${__b3bp_tmp_init}" =~ ${__b3bp_tmp_re} ]]; then
__b3bp_tmp_init="${BASH_REMATCH[1]}"
fi
fi
fi
fi
if [[ "${__b3bp_tmp_line}" =~ ^Required\. ]] || [[ "${__b3bp_tmp_line}" =~ \.\ *Required\. ]]; then
# remember that this option requires an argument
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "2"
fi
# Init var with value unless it is an array / a repeatable
__b3bp_tmp_varname="__b3bp_tmp_is_array_${__b3bp_tmp_opt:0:1}"
[[ "${!__b3bp_tmp_varname}" = "0" ]] && printf -v "arg_${__b3bp_tmp_opt:0:1}" '%s' "${__b3bp_tmp_init}"
done <<< "${__usage:-}"
# run getopts only if options were specified in __usage
if [[ "${__b3bp_tmp_opts:-}" ]]; then
# Allow long options like --this
__b3bp_tmp_opts="${__b3bp_tmp_opts}-:"
# Reset in case getopts has been used previously in the shell.
OPTIND=1
# start parsing command line
set +o nounset # unexpected arguments will cause unbound variables
# to be dereferenced
# Overwrite $arg_<flag> defaults with the actual CLI options
while getopts "${__b3bp_tmp_opts}" __b3bp_tmp_opt; do
[[ "${__b3bp_tmp_opt}" = "?" ]] && help "Invalid use of script: ${*} "
if [[ "${__b3bp_tmp_opt}" = "-" ]]; then
# OPTARG is long-option-name or long-option=value
if [[ "${OPTARG}" =~ .*=.* ]]; then
# --key=value format
__b3bp_tmp_long_opt=${OPTARG/=*/}
# Set opt to the short option corresponding to the long option
__b3bp_tmp_varname="__b3bp_tmp_opt_long2short_${__b3bp_tmp_long_opt//-/_}"
printf -v "__b3bp_tmp_opt" '%s' "${!__b3bp_tmp_varname}"
OPTARG=${OPTARG#*=}
else
# --key value format
# Map long name to short version of option
__b3bp_tmp_varname="__b3bp_tmp_opt_long2short_${OPTARG//-/_}"
printf -v "__b3bp_tmp_opt" '%s' "${!__b3bp_tmp_varname}"
# Only assign OPTARG if option takes an argument
__b3bp_tmp_varname="__b3bp_tmp_has_arg_${__b3bp_tmp_opt}"
__b3bp_tmp_varvalue="${!__b3bp_tmp_varname}"
[[ "${__b3bp_tmp_varvalue}" != "0" ]] && __b3bp_tmp_varvalue="1"
printf -v "OPTARG" '%s' "${@:OPTIND:${__b3bp_tmp_varvalue}}"
# shift over the argument if argument is expected
((OPTIND+=__b3bp_tmp_varvalue))
fi
# we have set opt/OPTARG to the short value and the argument as OPTARG if it exists
fi
__b3bp_tmp_value="${OPTARG}"
__b3bp_tmp_varname="__b3bp_tmp_is_array_${__b3bp_tmp_opt:0:1}"
if [[ "${!__b3bp_tmp_varname}" != "0" ]]; then
# repeatables
# shellcheck disable=SC2016
if [[ -z "${OPTARG}" ]]; then
# repeatable flags, they increcemnt
__b3bp_tmp_varname="arg_${__b3bp_tmp_opt:0:1}"
debug "cli arg ${__b3bp_tmp_varname} = (${__b3bp_tmp_default}) -> ${!__b3bp_tmp_varname}"
__b3bp_tmp_value=$((${!__b3bp_tmp_varname} + 1))
printf -v "${__b3bp_tmp_varname}" '%s' "${__b3bp_tmp_value}"
else
# repeatable args, they get appended to an array
__b3bp_tmp_varname="arg_${__b3bp_tmp_opt:0:1}[@]"
debug "cli arg ${__b3bp_tmp_varname} append ${__b3bp_tmp_value}"
declare -a "${__b3bp_tmp_varname}"='("${!__b3bp_tmp_varname}" "${__b3bp_tmp_value}")'
fi
else
# non-repeatables
__b3bp_tmp_varname="arg_${__b3bp_tmp_opt:0:1}"
__b3bp_tmp_default="${!__b3bp_tmp_varname}"
if [[ -z "${OPTARG}" ]]; then
__b3bp_tmp_value=$((__b3bp_tmp_default + 1))
fi
printf -v "${__b3bp_tmp_varname}" '%s' "${__b3bp_tmp_value}"
debug "cli arg ${__b3bp_tmp_varname} = (${__b3bp_tmp_default}) -> ${!__b3bp_tmp_varname}"
fi
done
set -o nounset # no more unbound variable references expected
shift $((OPTIND-1))
if [[ "${1:-}" = "--" ]] ; then
shift
fi
fi
### Automatic validation of required option arguments
##############################################################################
for __b3bp_tmp_varname in ${!__b3bp_tmp_has_arg_*}; do
# validate only options which required an argument
[[ "${!__b3bp_tmp_varname}" = "2" ]] || continue
__b3bp_tmp_opt_short="${__b3bp_tmp_varname##*_}"
__b3bp_tmp_varname="arg_${__b3bp_tmp_opt_short}"
[[ "${!__b3bp_tmp_varname}" ]] && continue
__b3bp_tmp_varname="__b3bp_tmp_opt_short2long_${__b3bp_tmp_opt_short}"
printf -v "__b3bp_tmp_opt_long" '%s' "${!__b3bp_tmp_varname}"
[[ "${__b3bp_tmp_opt_long:-}" ]] && __b3bp_tmp_opt_long=" (--${__b3bp_tmp_opt_long//_/-})"
help "Option -${__b3bp_tmp_opt_short}${__b3bp_tmp_opt_long:-} requires an argument"
done
### Cleanup Environment variables
##############################################################################
for __tmp_varname in ${!__b3bp_tmp_*}; do
unset -v "${__tmp_varname}"
done
unset -v __tmp_varname
### Externally supplied __usage. Nothing else to do here
##############################################################################
if [[ "${__b3bp_external_usage:-}" = "true" ]]; then
unset -v __b3bp_external_usage
return
fi
### Signal trapping and backtracing
##############################################################################
function __b3bp_cleanup_before_exit () {
info "Cleaning up. Done"
}
trap __b3bp_cleanup_before_exit EXIT
# requires `set -o errtrace`
__b3bp_err_report() {
local error_code=${?}
error "Error in ${__file} in function ${1} on line ${2}"
exit ${error_code}
}
# Uncomment the following line for always providing an error backtrace
# trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR
### Command-line argument switches (like -d for debugmode, -h for showing helppage)
##############################################################################
# debug mode
if [[ "${arg_d:?}" = "1" ]]; then
set -o xtrace
PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
LOG_LEVEL="7"
# Enable error backtracing
trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR
fi
# verbose mode
if [[ "${arg_v:?}" = "1" ]]; then
set -o verbose
fi
# no color mode
if [[ "${arg_n:?}" = "1" ]]; then
NO_COLOR="true"
fi
# help mode
if [[ "${arg_h:?}" = "1" ]]; then
# Help exists with code 1
help "Help using ${0}"
fi
### Validation. Error out if the things required for your script are not present
##############################################################################
[[ "${arg_f:-}" ]] || help "Setting a filename with -f or --file is required"
[[ "${LOG_LEVEL:-}" ]] || emergency "Cannot continue without LOG_LEVEL. "
### Runtime
##############################################################################
info "__i_am_main_script: ${__i_am_main_script}"
info "__file: ${__file}"
info "__dir: ${__dir}"
info "__base: ${__base}"
info "OSTYPE: ${OSTYPE}"
info "arg_f: ${arg_f}"
info "arg_d: ${arg_d}"
info "arg_v: ${arg_v}"
info "arg_h: ${arg_h}"
# shellcheck disable=SC2015
if [[ -n "${arg_i:-}" ]] && declare -p arg_i 2> /dev/null | grep -q '^declare \-a'; then
info "arg_i:"
for input_file in "${arg_i[@]}"; do
info " - ${input_file}"
done
elif [[ -n "${arg_i:-}" ]]; then
info "arg_i: ${arg_i}"
else
info "arg_i: 0"
fi
# shellcheck disable=SC2015
if [[ -n "${arg_x:-}" ]] && declare -p arg_x 2> /dev/null | grep -q '^declare \-a'; then
info "arg_x: ${#arg_x[@]}"
elif [[ -n "${arg_x:-}" ]]; then
info "arg_x: ${arg_x}"
else
info "arg_x: 0"
fi
info "$(echo -e "multiple lines example - line #1\\nmultiple lines example - line #2\\nimagine logging the output of 'ls -al /path/'")"
# All of these go to STDERR, so you can use STDOUT for piping machine readable information to other software
debug "Info useful to developers for debugging the application, not useful during operations."
info "Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required."
notice "Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required."
warning "Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time. This is a debug message"
error "Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time."
critical "Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection."
alert "Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection."
emergency "A \"panic\" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call."

11
nothing.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting&hellip;</title>
<link rel="canonical" href="/">
<script>location="/"</script>
<meta http-equiv="refresh" content="0; url=/">
<meta name="robots" content="noindex">
<h1>Redirecting&hellip;</h1>
<a href="/">Click here if you are not redirected.</a>
</html>

1
redirects.json Normal file
View File

@ -0,0 +1 @@
{"/CHANGELOG.md/":"/changelog/","/FAQ.md/":"/faq/","/nothing":"/"}