- Helpful magic variables like `__file`, `__dir`, and `__os`
- Logging that supports colors and is compatible with [Syslog Severity levels](http://en.wikipedia.org/wiki/Syslog#Severity_levels) as well as the [twelve-factor](http://12factor.net/) guidelines
We're looking for endorsement! Are you also using b3bp? [Let us know](https://github.com/kvz/bash3boilerplate/issues/new?title=I%20use%20b3bp) and get listed.
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.
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:
```bash
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.
```bash
# 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](https://raw.githubusercontent.com/bpkg/bpkg/master/README.md) project)
- Use `__double_underscore_prefixed_vars` to indicate global variables that are solely controlled inside your script, with the exception of arguments wich are already prefixed with `arg_`, and functions, over which b3bp poses no restrictions.
- Use `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`
- Use `BASH_SOURCE[0]` if you refer to current file even if it is sourced by a parent script. Otherwise use `${0}`
- Use `:-` if you want to test variables that could be undeclared. For instance: `if [ "${NAME:-}" = "Kevin" ]` will set `$NAME` to be empty if it's not declared instead of throwing an error. You can also set it to `noname` like so `if [ "${NAME:-noname}" = "Kevin" ]`
- Use long options (`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.
-`#!/usr/bin/env bash` is more portable than `#!/bin/bash`.
- Surround your variables with `{}`. Otherwise bash will try to access the `$ENVIRONMENT_app` variable in `/srv/$ENVIRONMENT_app`, whereas you probably intended `/srv/${ENVIRONMENT}_app`.
- You don't need two equal signs when checking `if [ "${NAME}" = "Kevin" ]`.