#!/usr/bin/env bash # Example Bash Shell Script # from https://betterdev.blog/minimal-safe-bash-script-template/ set -Eeuo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 # declare globals as readonly readonly SCRIPT_NAME SCRIPT_NAME="$(basename "$0")" trap cleanup SIGINT SIGTERM ERR EXIT usage() { cat <&2 -e "${1-}" } # more structured logging (better) log() { local -r level="$1" local -r message="$2" local -r timestamp=$(date +"%Y-%m-%d %H:%M:%S") # colorize your log output here, if desired echo >&2 -e "${timestamp} [${level}] [$SCRIPT_NAME] ${message}" } die() { local msg=$1 local code=${2-1} # default exit status 1 log "FATAL" "$msg" exit "$code" } assert_not_empty() { local -r arg_name="$1" local -r arg_value="$2" if [[ -z $arg_value ]]; then log "ERROR" "The value for '$arg_name' cannot be empty" exit 1 fi } assert_is_installed() { local -r name="$1" if [[ ! $(command -v "$name") ]]; then log "ERROR" "The binary '$name' is required by this script but is not installed or in the system's PATH." exit 1 fi } parse_params() { while :; do case "${1-}" in -h | --help) usage ;; -v | --verbose) set -x ;; --no-color) NO_COLOR=1 ;; -f | --flag) # example flag # FLAG=1 ;; -p | --param) # example named parameter assert_not_empty "--param", "${2-}" PARAM="${2-}" shift ;; -?*) die "Unknown option: $1" ;; *) break ;; esac shift done # check required params and arguments assert_is_installed "bash" return 0 } # default values of variables set from parse_params # to avoid having these variables here, you will need to define the work of # the script as another function that takes arguments and call it with local # variables declared in parse_params: # # run() { # local -r flag=$1 # } # # parse_params() { # local flag=0 # ... # run $flag # } FLAG=0 PARAM='' readonly ARGS=("$@") parse_params "$@" setup_colors # script logic here log "INFO" "${RED}Read parameters:${NOCOLOR}" log "INFO" "- flag: ${FLAG}" log "INFO" "- param: ${PARAM}" log "INFO" "- arguments: ${ARGS[*]-}"