-
-
Save aburd/fc3cd8f7420d648cba066693413e6e3c to your computer and use it in GitHub Desktop.
A Bash script model with common options (verbose, force etc) & minimal functions (error, usage etc) to use and re-use to build your own shell scripts easily.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Bash script model | |
# | |
# A Bash script model with common options (verbose, force etc) | |
# & minimal functions (error, usage etc) | |
# to use and re-use to build your own shell scripts easily. | |
# | |
# To begin, run one of the followings: | |
# | |
# ./shell-script-model.sh -h | |
# ./shell-script-model.sh --help | |
# ./shell-script-model.sh -x | |
# | |
# For last updates, see <https://gist.github.com/ee576171255463dbcc599454414ba8a5.git> | |
# | |
# bash options | |
#set -e | |
set -u | |
set -o pipefail | |
# edit the `SCRIPT_...` variables below to adapt to your script | |
SCRIPT_VERSION="0.0.1-dev" | |
SCRIPT_NAME="$0" | |
SCRIPT_PRESENTATION="This script is a bash script model." | |
IFS='' read -r -d '' SCRIPT_USAGE <<EOF | |
usage: $0 [-h | --help | -v/--verbose | -f/--force] [options [=value]] <arguments> | |
i.e.: $0 test | |
options: | |
-h see a short usage string and exit with status 0 | |
--help see a long help string and exit with status 0 | |
-v|--verbose enable verbosity | |
-f|--force enable force | |
EOF | |
# This model is designed to use the followings by default: | |
# | |
# - the `-h` option shows a simple "usage" string and exits with status 0 (no error) | |
# - the `--help` option shows a long "help" string and exits with status 0 (no error) | |
# - the `-v` or `--verbose` options enables the `VERBOSE` boolean variable | |
# - the `-f` or `--force` options enables the `FORCE` boolean variable | |
# - the `-x` option enables the `DEBUG` boolean variable (for development) | |
# | |
SCRIPT_OPTS_SHORT='fhvx' | |
SCRIPT_OPTS_LONG='force,help,verbose' | |
export SCRIPT_VERSION SCRIPT_NAME SCRIPT_PRESENTATION SCRIPT_USAGE SCRIPT_OPTS_SHORT SCRIPT_OPTS_LONG | |
# environment | |
VERBOSE=false | |
FORCE=false | |
DEBUG=false | |
declare -a DEBUG_DATA | |
# internal tracelog function | |
traceback () { | |
local -i start=$(( ${1:-0} + 1 )) | |
local -i end=${#BASH_SOURCE[@]} | |
local -i i=0 | |
local -i j=0 | |
echo " Traceback (last call is first):" 1>&2 | |
for ((i=${start}; i < ${end}; i++)); do | |
j=$(( $i - 1 )) | |
local function="${FUNCNAME[$i]}" | |
local file="${BASH_SOURCE[$i]}" | |
local line="${BASH_LINENO[$j]}" | |
echo " # ${function}() in ${file}:${line}" 1>&2 | |
done | |
} | |
# usage: die <error string> [traces nb=1] | |
die () { | |
{ echo '---' | |
echo "!! > $1" | |
traceback "${2:-1}" | |
echo '---' | |
} 1>&2 | |
exit 2 | |
} | |
# usage: get_absolute_path <path> | |
get_absolute_path() { | |
[ $# -eq 0 ] && die 'usage: get_absolute_path <path>'; | |
local cwd="$(pwd)" | |
local path="$1" | |
while [ -n "$path" ]; do | |
cd "${path%/*}" 2>/dev/null; | |
local name="${path##*/}" | |
path="$($(type -p greadlink readlink | head -1) "$name" || true)" | |
done | |
pwd | |
cd "$cwd" | |
} | |
# usage: usage | |
usage () { | |
echo "${SCRIPT_USAGE}" | |
} | |
# usage: help | |
help () { | |
cat <<EOT | |
## ${SCRIPT_NAME} - ${SCRIPT_VERSION} ## | |
${SCRIPT_PRESENTATION} | |
${SCRIPT_USAGE} | |
EOT | |
} | |
# usage: error [str=''] | |
error () { | |
{ echo '---' | |
echo "> $*" | |
echo '---' | |
usage | |
} 1>&2 | |
exit 1 | |
} | |
# usage: verbose_echo <string to print if verbosity is on> | |
verbose_echo () { | |
$VERBOSE && echo "$*"; | |
} | |
# library dir | |
BASEDIR="$(get_absolute_path "${BASH_SOURCE[0]}")" | |
# arguments | |
PARSED_OPTS=$( | |
getopt --name "$0" --options "$SCRIPT_OPTS_SHORT" --longoptions "$SCRIPT_OPTS_LONG" -- "$@" | |
) || error "script parameters error!"; | |
eval "set -- $PARSED_OPTS"; | |
for opt in "$@"; do | |
case "$opt" in | |
-f|--force) | |
FORCE=true | |
shift | |
;; | |
-h) | |
usage | |
exit 0 | |
;; | |
--help) | |
help | |
exit 0 | |
;; | |
-v|--verbose) | |
VERBOSE=true | |
shift | |
;; | |
-x) | |
DEBUG=true | |
shift | |
;; | |
--) | |
shift | |
continue | |
;; | |
esac | |
done | |
export VERBOSE FORCE DEBUG DEBUG_DATA | |
#### command starts here... #### | |
# some tests | |
echo 'YO' | |
verbose_echo 'YO (verbose)' | |
DEBUG_DATA+=( test1 ) | |
DEBUG_DATA+=( test2 ) | |
# loop over user arguments | |
for i in "$@"; do | |
echo "> $i" | |
done | |
#### command ends here... #### | |
# debug environment | |
$DEBUG && ( | |
{ echo "[dbg] ////" | |
echo "[dbg] > CALL REBUILT : $*" | |
echo "[dbg] > VERBOSE : $VERBOSE" | |
echo "[dbg] > FORCE : $FORCE" | |
echo "[dbg] > DEBUG : $DEBUG" | |
echo "[dbg] > DEBUG DATA : ${DEBUG_DATA[@]}" | |
echo "[dbg] ////" | |
} 1>&2 | |
); | |
# exit status | |
exit 0 | |
# vim: autoindent tabstop=4 shiftwidth=4 expandtab softtabstop=4 filetype=sh |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment