Skip to content

Instantly share code, notes, and snippets.

@clemtibs
Last active November 13, 2023 10:48
Show Gist options
  • Select an option

  • Save clemtibs/5f97039fc25b03be76f17d13b1a05a03 to your computer and use it in GitHub Desktop.

Select an option

Save clemtibs/5f97039fc25b03be76f17d13b1a05a03 to your computer and use it in GitHub Desktop.
Quick and Dirty Bash Script Template
#!/bin/bash
##----------------
export script_name='Bash Script.sh'
export script_short_desc="
A script for doing things."
export script_mod_date='0000.00.00-00:00'
export script_version='0.0.1'
export script_requirements='none'
##----------------
shopt -s extglob ## Needed for arg parsing
## Config
export working_dir=${working_dir:-"$PWD"}
export script_subcommands_args=("")
## Script
do_work() {
echo "doing work in ${working_dir}"
}
## Args
parseArgs() {
local args=("$@")
while (( "${#args}" )); do
case "$1" in
-@([a-z|A-Z]*))
# Switches
parseSwitches "$1"
;;
--*)
# Options
parseOptions "$1"
;;
*)
# Subcommands args stored as an array for later. For more
# complicated scripts, sometimes we need to act on the
# switches/options or source configuration first before we run
# the subcommands.
script_subcommands_args=("$@")
break
;;
esac
shift
args=("$@")
done
shopt -u extglob
}
parseSwitches() {
local switches="$1"
switches="${switches:1}"
while (( "${#switches}" )); do
# Handle actions for individual switches here
case "${switches:0:1}" in
h)
usage
exit 0
;;
v)
version
exit 0
;;
*)
echo "Error: "${switches:0:1}" not a valid switch"
echo ""
usage
exit 1
;;
esac
switches="${switches:1}"
done
}
parseOptions() {
IFS='='
local option=(${1})
unset IFS
local option_keyword=${option[0]:2}
# Get value of option if there is any
local option_value=${option[@]:1}
# Handle actions for individual options here
case "${option_keyword}" in
help)
usage
exit 0
;;
version)
version
exit 0
;;
*)
echo "Error: "${option_keyword}" not a valid option"
echo ""
usage
exit 1
;;
esac
}
parseSubcommands() {
local args=("$@")
while (( "${#args}" )); do
case "$1" in
work)
echo "Args passed to work command: ${args[@]:1}"
break
;;
*)
echo "Error: "$1" not a valid subcommand"
usage
exit 1
;;
esac
shift
args=("$@")
done
}
## Dialogs
usage() {
cat <<EOF
Usage: "${script_name}" <args>
${script_short_desc}
Switches can be combined, or used individually, in any order. Options must
follow the format --option="something here" and not have spaces in between
the option keyword and it's value.
By default:
- Any arguments that aren't switches or options are treated as erroneous, but
they could potentially be main arguments subcommands.
- The script processes all switches and all options, but stops only if
"exit" is declared in any of the 'case' statements. This is the current
behavior but can be easily changed.
Switches/Options:
-v|--version Version
-h|--help This help
Subcommands
work Werk it
Requirements:
${script_requirements}
Version:
${script_name} version: ${script_version}
Last modifed on: ${script_mod_date}
EOF
}
version() {
echo "${script_name} version: ${script_version}"
echo "Last modifed on: ${script_mod_date}"
}
## Sequence
main() {
set -eo pipefail
parseArgs "$@"
parseSubcommands "${script_subcommands_args[@]}"
# Default behavior
do_work
}
## Runtime
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment