• Stars
    star
    2,092
  • Rank 22,081 (Top 0.5 %)
  • Language
    Shell
  • License
    MIT License
  • Created over 11 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Templates to write better Bash scripts

Overview

When hacking up Bash scripts, there are often things such as logging or command-line argument parsing that:

  • You need every time
  • Come with a number of pitfalls you want to avoid
  • Keep you from your actual work

Here's an attempt to bundle those things in a generalized way so that they are reusable as-is in most scripts.

We call it "BASH3 Boilerplate" or b3bp for short.

Goals

Delete-Key-Friendly. Instead of introducing packages, includes, compilers, etc., we propose using main.sh 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.

Portable. 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.

Features

  • Conventions that will make sure that all your scripts follow the same, battle-tested structure
  • Safe by default (break on error, pipefail, etc.)
  • Configuration by environment variables
  • Simple command-line argument parsing that requires no external dependencies. Definitions are parsed from help info, ensuring there will be no duplication
  • Helpful magic variables like __file and __dir
  • Logging that supports colors and is compatible with Syslog Severity levels, as well as the twelve-factor guidelines

Installation

There are three different ways to install b3bp:

Option 1: Download the main template

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.

wget http://bash3boilerplate.sh/main.sh
vim main.sh

Option 2: Clone the entire project

Besides main.sh, this will also get you the entire b3bp repository. This includes a few extra functions that we keep in the ./src directory.

git clone [email protected]:kvz/bash3boilerplate.git

Option 3: Require via npm

As of v1.0.3, b3bp can also be installed as a Node module, meaning you can define it as a dependency in package.json via:

npm init
npm install --save --save-exact bash3boilerplate

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.

Changelog

Please see the CHANGELOG.md file.

Frequently Asked Questions

Please see the FAQ.md file.

Best practices

As of v1.0.3, b3bp offers some nice re-usable libraries in ./src. In order to make the snippets in ./src more useful, we recommend the following guidelines.

Function packaging

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 should follow this pattern:

if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then
  my_script "${@}"
  exit $?
fi
export -f my_script

This allows a user to source your script or invoke it as a script.

# Running as a script
$ ./my_script.sh some args --blah
# Sourcing the script
$ source my_script.sh
$ my_script some more args --blah

(taken from the bpkg project)

Scoping

  1. In functions, use local before every variable declaration.
  2. Use UPPERCASE_VARS to indicate environment variables that can be controlled outside your script.
  3. Use __double_underscore_prefixed_vars to indicate global variables that are solely controlled inside your script, with the exception of arguments that are already prefixed with arg_, as well as functions, over which b3bp poses no restrictions.

Coding style

  1. Use two spaces for tabs, do not use tab characters.
  2. Do not introduce whitespace at the end of lines or on blank lines as they obfuscate version control diffs.
  3. Use long options (logger --priority vs logger -p). 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 set -o nounset over set -u.
  4. Use a single equal sign when checking if [[ "${NAME}" = "Kevin" ]]; double or triple signs are not needed.
  5. Use the new bash builtin test operator ([[ ... ]]) rather than the old single square bracket test operator or explicit call to test.

Safety and Portability

  1. Use {} to enclose your variables. Otherwise, Bash will try to access the $ENVIRONMENT_app variable in /srv/$ENVIRONMENT_app, whereas you probably intended /srv/${ENVIRONMENT}_app. Since it is easy to miss cases like this, we recommend that you make enclosing a habit.
  2. Use set, rather than relying on a shebang like #!/usr/bin/env bash -e, since that is neutralized when someone runs your script as bash yourscript.sh.
  3. Use #!/usr/bin/env bash, as it is more portable than #!/bin/bash.
  4. Use ${BASH_SOURCE[0]} if you refer to current file, even if it is sourced by a parent script. In other cases, use ${0}.
  5. Use :- if you want to test variables that could be undeclared. For instance, with if [[ "${NAME:-}" = "Kevin" ]], $NAME will evaluate to Kevin if the variable is empty. The variable itself will remain unchanged. The syntax to assign a default value is ${NAME:=Kevin}.

Who uses b3bp?

We are looking for endorsements! Are you also using b3bp? Let us know and get listed.

Authors

License

Copyright (c) 2013 Kevin van Zonneveld and contributors. Licensed under MIT. 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.

More Repositories

1

json2hcl

Convert JSON to HCL, and vice versa. We don't use json2hcl anymore ourselves, so we can't invest time into it. However, we're still welcoming PRs.
HCL
504
star
2

cronlock

cronlock lets you deploy cronjobs cluster-wide without worrying about overlaps. It uses Redis to keep track of locks.
Shell
268
star
3

system_daemon

Discontinued. All the boilerplate required to daemonize php
PHP
143
star
4

nsfailover

Let's Make DNS Outage Suck Less
Shell
102
star
5

ochtra

One Commit Hook To Rule All
Shell
85
star
6

invig

🌿 Invig automatically converts ES5 & CoffeeScript codebases to ES6 with Aligned JavaScript Standard Style
JavaScript
62
star
7

metriks

[UNMAINTAINED] A lightweight server graphing framework
JavaScript
56
star
8

cakephp-elasticsearch-plugin

Discontinued. CakePHP plugin for Elasticsearch: the Open Source, Distributed, RESTful, Search Engine
PHP
45
star
9

logstreamer

Prefixes streams (e.g. stdout or stderr) in Go
Go
45
star
10

fakefile

The Universal Makefile for JavaScript
JavaScript
41
star
11

lanyon

Deprecated
JavaScript
35
star
12

eventcache

Discontinued. PHP caching & invalidation for the lazy coder
PHP
15
star
13

airbud

Retrieving stuff from the web is unreliable. Airbud adds retries for production, and fixture support for test.
CoffeeScript
15
star
14

environmental

Node project that aims to provide code and conventions to deal with environment vars for configuration in a structured, reusable, pleasant way
JavaScript
13
star
15

packing-list

An MIT Licensed packing list for short trips abroad
12
star
16

deprecated

My deprecated repositories are now separate branches in this repository
12
star
17

on-the-githubs

Aggregates GitHub community activity as seen on http://tus.io and http://uppy.io .
JavaScript
11
star
18

rotation

Generate filenames suitable for backup rotation
JavaScript
9
star
19

node-depurar

Node.js debugging for the truly lazy
CoffeeScript
7
star
20

youtube-id

PHP
5
star
21

ec2-instances-list

Compare all EC2 instances in one sortable table
CSS
5
star
22

baseamp

Convert your Markdown todo lists to Basecamp Todolists and back
CoffeeScript
4
star
23

scrolex

Execute commands, scroll back the stdout & stderr, prefix by user-defined categories
JavaScript
4
star
24

riak-formation

Create/restore a riak cluster on any cloudprovider using Terraform
Shell
3
star
25

cakephp-ipv6-plugin

Discontinued. Plugin-wrapped CakePHP behavior to work with IPv6 addresses with efficient MySQL storage
PHP
3
star
26

huemidoro

Turns all your Philips HUE lamps red when it's time for a break :)
CoffeeScript
3
star
27

ratestate

A ratelimiter that can transmit states of different entities while avoiding transmitting the same state twice, and adhering to a global speed limit.
CoffeeScript
3
star
28

dialout

☎️➡️
JavaScript
2
star
29

x264

C
1
star
30

sledge

🔨
CoffeeScript
1
star
31

jekyll-fix-titlecase

Fixes title casing in markdown blogposts. Uppercases all words except for code, abbreviations, 'and', 'the', 'a', etc.
JavaScript
1
star