kvz / bash3boilerplate
- пятница, 24 июня 2016 г. в 03:12:56
Shell
Templates to write better Bash scripts
When hacking up Bash scripts, there are often things such as logging or command-line argument parsing that:
Here's an attempt to bundle those things in a generalized way so that they are reusable as-is in most scripts.
Delete-Key-Friendly. We propose using main.sh
as a base and removing the parts you don't need, rather than introducing packages, includes, compilers, etc.
This may feel a bit archaic at first, but that is exactly the strength of Bash scripts that we want to embrace.
Portable. We're targeting Bash 3 (OSX still ships with 3 for instance). If you're going to ask people to install Bash 4 first, you might as well pick a more advanced language as a dependency.
__file
, __dir
, and __os
We're looking for endorsement! Are you also using b3bp? Let us know and get listed.
There are 3 different ways you can install b3bp:
Use curl or wget to download the source, save as your script, and start deleting the unwanted bits, and adding your own logic.
wget https://raw.githubusercontent.com/kvz/bash3boilerplate/master/main.sh
vim main.sh
Besides main.sh
, this will get you the entire b3bp repository including a few extra functions that we keep in the ./src
directory.
git clone git@github.com:kvz/bash3boilerplate.git
As of v1.0.3
, b3bp can also be installed as a Node module so you can define it as a dependency in package.json
via:
npm init
npm install --save --save-exact bash3boilerplate
Although this option introduces a Node.js dependency, this does allow for easy version pinning and distribution in environments that already have this prerequisite. But, this is optional and nothing prevents you from ignoring this possibility.
Please see the CHANGELOG.md file.
As of v1.0.3
, b3bp adds some nice re-usable libraries in ./src
. In order to make the snippets in ./src
more useful, we recommend these guidelines.
It's nice to have a Bash package that can be used in the terminal and also be invoked as a command line function. To achieve this the exporting of your functionality should follow this pattern:
if [ "${BASH_SOURCE[0]}" != "${0}" ]; then
export -f my_script
else
my_script "${@}"
exit $?
fi
This allows a user to source
your script or invoke 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)
local
before every variable declarationUPPERCASE_VARS
to indicate environment variables that can be controlled outside your script__double_underscore_prefixed_vars
to indicate global variables that are solely controlled inside your script, with the exception of arguments which are already prefixed with arg_
, and functions, over which b3bp poses no restrictions.logger --priority
vs logger -p
). If you're on cli, abbreviations make sense for efficiency. but when you're writing reusable scripts a few extra keystrokes will pay off in readability and avoid ventures into man pages in the future by you or your collaborators. Similarly, we prefer set -o nounset
over set -u
.if [ "${NAME}" = "Kevin" ]
, double or triple signs are not needed.{}
to enclose your variables in. Otherwise Bash will try to access the $ENVIRONMENT_app
variable in /srv/$ENVIRONMENT_app
, whereas you probably intended /srv/${ENVIRONMENT}_app
. Since it's easy to miss cases like this, we recommend making enclosing a habit.set
rather than relying on a shebang like #!/usr/bin/env bash -e
as that is neutralized when someone runs your script as bash yourscript.sh
#!/usr/bin/env bash
as it is more portable than #!/bin/bash
.${BASH_SOURCE[0]}
if you refer to current file even if it is sourced by a parent script. Otherwise use ${0}
:-
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}
.Please see the FAQ.md file.
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 header comments of your source files.