Bash Style Guide ================ Basic ----- * Indent: two spaces. Spaces >> tabs. Creating `usage()` and `help()` ------------------------------- The general semantics --------------------- When the user requests help through `-h` or no arguments, `show_help()` should be used. This will output the info on stdout because the user explicitly requested so. If the user gives some form of invalid argument or there is any other error the usage should go to stderr because the user might be using pipes. How app.sh does it ------------------ Each command should implement `usage_text`. The command should call `show_help()` and `usage()` as appropriate. These functions are defined in `lib/common` and will both call `usage_app()` to get the usage info. `usage()` will send the info to stderr. * `show_help()` will exit with 0, while `usage()` will exit with code 1. Formatting of usage output -------------------------- * Enclose required arguments in angle brackets: `-v ` * Enclose optional arguments in square brackets: `[-h hook]` ---------------------------------------------------------------------- usage_text() { echo "usage: $usage_app -v [-h hook]" } ---------------------------------------------------------------------- Executing Commands ================== When chaining commands look at `pipefail`. * http://unix.stackexchange.com/q/23026 If you want to fail this shell if a sub-shell fails, use this form: ---------------------------------------------------------------------- ENV=$(app conf get app.env) || false ---------------------------------------------------------------------- The sub-shell will exit with a non-zero exit code, but even with `-e` set bash won't exit the current shell. See also http://www.fvue.nl/wiki/Bash:_Error_handling. Parsing options =============== Applications should always check for extra options or define how they're handled. By always shifting out processed arguments `$@` will be an array with the remaining arguments. If only command options are allowed they can be shifted in one go with the expression `shift $(($OPTIND - 1))`. ---------------------------------------------------------------------- while getopts "f:" opt do case $opt in f) file="$OPTARG" shift 2; ;; *) usage "Unknown argument: $OPTARG" ;; esac done shift $(($OPTIND - 1)) ---------------------------------------------------------------------- After all arguments have been processed, check for extra arguments: ---------------------------------------------------------------------- if [[ $# != 0 ]] then usage "Extra arguments" fi ---------------------------------------------------------------------- Resources --------- * Parameter expansion: // vim: set ft=asciidoc: