Update website by travis
11
CHANGELOG.md/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting…</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…</h1>
|
||||
<a href="/changelog/">Click here if you are not redirected.</a>
|
||||
</html>
|
11
FAQ.md/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting…</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…</h1>
|
||||
<a href="/faq/">Click here if you are not redirected.</a>
|
||||
</html>
|
1
README.md
Normal 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
@ -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');
|
||||
});
|
||||
}
|
BIN
assets/build/3ba26992cc37ef2daa33df4f95c38c5c.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
1
assets/build/app.a6d50511e193d4224561.css
Normal file
2
assets/build/app.a6d50511e193d4224561.js
Normal 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
|
1
assets/build/app.a6d50511e193d4224561.js.map
Normal file
208
assets/build/stats.html
Normal file
BIN
assets/images/1.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/images/b3bp-logo.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
assets/images/logo.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
assets/images/logo.pxm
Normal file
BIN
assets/images/logos/bash3boilerplate_logo_darkbackground.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 563 KiB |
BIN
assets/images/logos/bash3boilerplate_logo_darkbackground_RGB.eps
Normal file
BIN
assets/images/logos/bash3boilerplate_logo_darkbackground_RGB.jpg
Normal file
After Width: | Height: | Size: 349 KiB |
404
assets/images/logos/bash3boilerplate_logo_darkbackground_RGB.pdf
Normal file
BIN
assets/images/logos/bash3boilerplate_logo_whitebackground.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 543 KiB |
After Width: | Height: | Size: 345 KiB |
55
assets/main.js
Normal 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="/">« 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
@ -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
@ -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
@ -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>Here’s 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> doesn’t 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 & 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, don’t 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 & 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
@ -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 Bash’s <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 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="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 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="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
@ -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>Here’s 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 don’t need.
|
||||
While this may feel a bit archaic at first, it is exactly the strength of Bash scripts that we should want to embrace.</p>
|
||||
|
||||
<p><strong>Portable</strong>. We are targeting Bash 3 (OSX still ships
|
||||
with 3, for instance). If you are going to ask people to install
|
||||
Bash 4 first, you might as well pick a more advanced language as a
|
||||
dependency.</p>
|
||||
|
||||
<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
@ -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
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting…</title>
|
||||
<link rel="canonical" href="/">
|
||||
<script>location="/"</script>
|
||||
<meta http-equiv="refresh" content="0; url=/">
|
||||
<meta name="robots" content="noindex">
|
||||
<h1>Redirecting…</h1>
|
||||
<a href="/">Click here if you are not redirected.</a>
|
||||
</html>
|
1
redirects.json
Normal file
@ -0,0 +1 @@
|
||||
{"/CHANGELOG.md/":"/changelog/","/FAQ.md/":"/faq/","/nothing":"/"}
|