• Stars
    star
    699
  • Rank 62,455 (Top 2 %)
  • Language
    Shell
  • License
    MIT License
  • Created over 9 years ago
  • Updated about 2 years ago

Reviews

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

Repository Details

A collection of Bash scripts for creating safe and useful command line programs.

Build Status

Bash Boilerplate

A collection of Bash starter scripts for easily creating safe and useful command line programs.

Bash Boilerplate is great for making standalone, portable, single-file command line programs as well as shell initialization functions. For a framework approach that's useful for task and build files, try Bask, a pure Bash mini-framework for command-centric Bash scripts.

Scripts

bash-simple

A simple bash script with some basic strictness checks and help features. Useful for simple programs that don't have many features and don't take options other than help.

Notable Features
  • Strict Mode,
  • Help template, printable with -h or --help.

bash-simple-plus

A simple bash script with some basic strictness checks, option parsing, help features, easy debug printing. Useful for regular scripts.

Notable Features
  • Strict Mode,
  • Help template, printable with -h or --help,
  • debug printing with --debug flag,
  • _exit_1 and _warn functions for error messages,
  • Option parsing.

bash-subcommands

An example of a bash program with subcommands. This contains lots of features and should be usable for creating bash programs that do multiple related tasks.

Notable Features
  • Strict Mode,
  • Help template, printable with -h or --help,
  • debug printing with --debug flag,
  • _exit_1 and _warn functions for error messages,
  • Option normalization and parsing,
  • Automatic arbitrary subcommand loading,
  • An nice, clean pattern for specifying per-subcommand help,
  • Built-in subcommands for help, version, and subcommand listing,
  • Conventions for distinguishing between functions and program subcommands,
  • Useful utility functions.

functions.bash

Shell function examples and boilerplate. The functions in this file are intended to be included in the interactive shell, which can be done by defining them in a shell init file like ~/.bashrc.

helpers.bash

Helper functions. These functions are primarily intended to be used within scripts, but can be adapted for use as shell functions.

Notes

ShellCheck

Use it. It's super useful.

ShellCheck is a static analysis and linting tool for sh/bash scripts. It's mainly focused on handling typical beginner and intermediate level syntax errors and pitfalls where the shell just gives a cryptic error message or strange behavior, but it also reports on a few more advanced issues where corner cases can cause delayed failures.

Links

It can be used with Vim via Syntastic, Emacs via Flycheck, Sublime Text 3 via SublimeLinter, VS Code via vscode-shellcheck, and Atom via linter, atom-lint, or linter-shellcheck.


Bash "Strict Mode"

These boilerplate scripts use some common settings for enforcing strictness in Bash scripts, thereby preventing some errors.

For some additional background, see Aaron Maxwell's "Unofficial Bash Strict Mode" (redsymbol.net) post.


Simple 'Strict Mode' TL;DR

Add this to the top of every script (note: an extended version of this is already included in the boilerplate scripts):

# Bash 'Strict Mode'
# http://redsymbol.net/articles/unofficial-bash-strict-mode
# https://github.com/xwmx/bash-boilerplate#bash-strict-mode
set -o nounset
set -o errexit
set -o pipefail
IFS=$'\n\t'

set -o nounset / set -u

Treat unset variables and parameters other than the special parameters @ or * as an error when performing parameter expansion. An 'unbound variable' error message will be written to the standard error, and a non-interactive shell will exit.

Usage

Short form:

set -u

Long form:

set -o nounset
Parameter Expansion

Parameter expansion can be used to test for unset variables when using set -o nounset.

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

The two approaches that are probably the most appropriate are:

${parameter:-word}
  If parameter is unset or null, the expansion of word is substituted.
  Otherwise, the value of parameter is substituted. In other words, "word"
  acts as a default value when the value of "$parameter" is blank. If "word"
  is not present, then the default is blank (essentially an empty string).

${parameter:?word}
  If parameter is null or unset, the expansion of word (or a message to that
  effect if word is not present) is written to the standard error and the
  shell, if it is not interactive, exits. Otherwise, the value of parameter
  is substituted.
Parameter Expansion Examples

Arrays:

${some_array[@]:-}              # blank default value
${some_array[*]:-}              # blank default value
${some_array[0]:-}              # blank default value
${some_array[0]:-default_value} # default value: the string 'default_value'

Positional variables:

${1:-alternative} # default value: the string 'alternative'
${2:-}            # blank default value

With an error message:

${1:?'error message'}  # exit with 'error message' if variable is unbound

set -o errexit / set -e

Exit immediately if a pipeline returns non-zero.

Usage

Short form:

set -e

Long form:

set -o errexit
Using set -o errexit with read -rd ''

set -o errexit is super useful for avoiding scary errors, but there are some things to watch out for. When using read -rd '' with a heredoc, the exit status is non-zero, even though there isn't an error, and this setting then causes the script to exit. read -rd '' is equivalent to read -d $'\0', which means read until it finds a NUL byte, but it reaches the end of the heredoc without finding one and exits with a 1 status. Therefore, when reading from heredocs with set -e, there are three potential solutions:

Solution 1. set +e / set -e again:

set +e
read -rd '' variable <<HEREDOC
Example text.
HEREDOC
set -e

Solution 2. <<HEREDOC || true:

read -rd '' variable <<HEREDOC || true
Example text.
HEREDOC

Solution 3. Don't use set -e or set -o errexit at all.

More information:

'builtin "read -d" behaves differently after "set -e"' (lists.gnu.org)


set -o pipefail

Return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully.

Usage

Long form (no short form available):

set -o pipefail

$IFS

Set IFS to just newline and tab.

IFS=$'\n\t'

For some background, see Filenames and Pathnames in Shell: How to do it Correctly (dwheeler.com)


Misc Notes

Explicitness and clarity are generally preferable, especially since bash can be difficult to read. This leads to noisier, longer code, but should be easier to maintain. As a result, some general design preferences:

  • Use leading underscores on internal variable and function names in order to avoid name collisions. For unintentionally global variables defined without local, such as those defined outside of a function or automatically through a for loop, prefix with double underscores.
  • Always use braces when referencing variables, preferring ${NAME} instead of $NAME. Braces are only required for variable references in some cases, but the cognitive overhead involved in keeping track of which cases require braces can be reduced by simply always using them.
  • Prefer printf over echo. For more information, see: http://unix.stackexchange.com/a/65819
  • Prefer $_explicit_variable_name over names like $var.
  • Use the #!/usr/bin/env bash shebang in order to run the preferred Bash version rather than hard-coding a bash executable path.
  • Prefer splitting statements across multiple lines rather than writing one-liners.
  • Group related code into sections with large, easily scannable headers.
  • Describe behavior in comments as much as possible, assuming the reader is a programmer familiar with the shell, but not necessarily experienced writing shell scripts.

Resources

Related Projects

Examples

Scripts based on this project.

  • airport - A command line tool for Wi-Fi on macOS.
  • bask - A pure Bash mini-framework for command-centric Bash scripts.
  • bindle - A configuration and dotfile management tool for your personal unix-like computer.
  • hosts - Command line hosts file editor in a single portable script.
  • ❯ nb - CLI note-taking, bookmarking, and archiving with encryption, advanced search, Git-backed versioning and syncing, Pandoc-backed conversion, and more in a single portable script.
  • notes-app-cli - A command line interface for Notes.app on macOS.
  • pb - A tiny wrapper combining pbcopy & pbpaste in a single command.
  • search.sh - A command line search multi-tool.
  • user - Command line interface for common macOS user account operations.
  • vbox - A streamlined interface for VBoxManage, the VirtualBox command line tool.

Copyright (c) 2015 William Melody • [email protected]

More Repositories

1

nb

CLI and local web plain text note‑taking, bookmarking, and archiving with linking, tagging, filtering, search, Git versioning & syncing, Pandoc conversion, + more, in a single portable script.
Shell
6,205
star
2

pandoc-ruby

Ruby wrapper for Pandoc
Ruby
330
star
3

hosts

A command line hosts file editor in one portable script.
Shell
156
star
4

airport

A command line / terminal tool for Wi-Fi on macOS / OS X.
Shell
62
star
5

iso-639

Ruby gem with ISO 639-1 and ISO 639-2 language code entries and convenience methods.
Ruby
60
star
6

bindle

A configuration and dotfile management tool for your personal unix-like computer.
Shell
53
star
7

notes-app-cli

A command line interface for Notes.app on macOS.
Shell
51
star
8

bask

A runner and framework for command-centric Bash scripts.
Shell
39
star
9

vbox

A streamlined interface for VBoxManage, the VirtualBox command line tool.
Shell
36
star
10

dotvim

A full-featured configuration for Vim, Neovim, and MacVim.
Vim Script
30
star
11

osx-cli

A collection of command line shortcuts for common OS X operations.
Shell
24
star
12

pb

A tiny wrapper combining pbcopy & pbpaste in a single command.
Shell
24
star
13

dotfiles

A user environment for Unix-like systems.
Shell
21
star
14

search.sh

A command line search multi-tool.
Shell
21
star
15

redmine_restructuredtext_formatter

reStructuredText formatting for Redmine
Ruby
19
star
16

rbst

A Ruby gem for processing reStructuredText via Python's Docutils
Ruby
18
star
17

astral

A Zsh theme with contextual information and Zen mode.
Shell
14
star
18

user

Command line interface for common macOS user account operations.
Shell
10
star
19

bibliography

TeX
10
star
20

dotfile-research

A collection of items and submodules related to dotfiles.
Shell
8
star
21

spotlight-actions

Use Spotlight on macOS for fast user switching, locking the screen, putting the system to sleep, and other actions.
Shell
6
star
22

starters

A collection of starting points, skeletons, and boilerplate code.
Roff
6
star
23

orphans

Shell
5
star
24

thepub

Extraction of Repub's epub module and related tests
Ruby
5
star
25

landing-page

A very simple Sinatra application as described by Joel Gascoigne for creating a landing page hosted using Heroku and MongoHQ free plans
JavaScript
4
star
26

glyph_imager

Ruby
4
star
27

descendant_nav_tabs

Easy, customizable Rails navigation tabs. Active tab highlighting with a descendant CSS selector.
Ruby
4
star
28

makefile-for-tasks-boilerplate

Shell
3
star
29

dsgn

A simple workflow for design projects.
Shell
3
star
30

an_acl

Rails ACL
Ruby
3
star
31

dict

A command line tool written in Swift for querying definitions from OS X's dictionary.
Swift
3
star
32

parent_resources

DRYing Up Polymorphic Controllers
Ruby
3
star
33

lcclasses

Ruby gem for listing and manipulating Library of Congress Classification classes and subclasses
Ruby
3
star
34

homebrew-taps

My Homebrew formulae.
Ruby
3
star
35

git-mkrepo

Initialize a git repository.
Shell
3
star
36

picky_color

JS color picker based on Prototype/Scriptaculous
JavaScript
2
star
37

git-nest

Improved git subtrees (hopefully).
Shell
2
star
38

kindler

Ruby Kindle library
Ruby
2
star
39

shell-app

Turn a shell script into an OS X application.
Ruby
2
star
40

user_stats

A Sinatra-based middleware plugin template for displaying a user metrics dashboard in Rails applications
Ruby
2
star
41

swiftly

Transparent compilation for Swift command line scripts / programs.
Shell
1
star
42

autocap

My Capistrano Junk Drawer
Ruby
1
star
43

dev-box-examples

A collection of development boxes based on Vagrant and Docker.
1
star
44

jwysiwyg

Fork of jWYSIWYG javascript text editor
1
star
45

sanitize_css

Sanitize CSS using a whitelist
Ruby
1
star
46

alias-app

Create an OS X "alias" application that simply opens another OS X application.
Ruby
1
star