mirror of
https://github.com/octoleo/hosts.git
synced 2025-01-01 05:31:49 +00:00
Improve option parsing and command detection.
This commit is contained in:
parent
5d9f876b13
commit
7301dc38f1
209
hosts
209
hosts
@ -138,99 +138,6 @@ die() {
|
||||
_die echo "${@}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Options
|
||||
#
|
||||
# NOTE: The `getops` builtin command only parses short options and BSD `getopt`
|
||||
# does not support long arguments (GNU `getopt` does), so the most portable
|
||||
# and clear way to parse options is often to just use a `while` loop.
|
||||
#
|
||||
# For a pure bash `getopt` function, try pure-getopt:
|
||||
# https://github.com/agriffis/pure-getopt
|
||||
#
|
||||
# More info:
|
||||
# http://wiki.bash-hackers.org/scripting/posparams
|
||||
# http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
||||
# http://stackoverflow.com/a/14203146
|
||||
# http://stackoverflow.com/a/7948533
|
||||
# https://stackoverflow.com/a/12026302
|
||||
# https://stackoverflow.com/a/402410
|
||||
###############################################################################
|
||||
|
||||
# Get raw options for any commands that expect them.
|
||||
_RAW_OPTIONS="${*:-}"
|
||||
|
||||
# Parse Options ###############################################################
|
||||
|
||||
# Initialize $_COMMAND_ARGV array
|
||||
#
|
||||
# This array contains all of the arguments that get passed along to each
|
||||
# command. This is essentially the same as the program arguments, minus those
|
||||
# that have been filtered out in the program option parsing loop. This array
|
||||
# is initialized with $0, which is the program's name.
|
||||
_COMMAND_ARGV=("${0}")
|
||||
# Initialize $_CMD and `$_USE_DEBUG`, which can continue to be blank depending
|
||||
# on what the program needs.
|
||||
_CMD=""
|
||||
_USE_DEBUG=0
|
||||
_AUTO_SUDO=0
|
||||
|
||||
while [[ ${#} -gt 0 ]]
|
||||
do
|
||||
__opt="${1}"
|
||||
|
||||
shift
|
||||
|
||||
case "${__opt}" in
|
||||
-h|--help)
|
||||
_CMD="help"
|
||||
;;
|
||||
--version)
|
||||
_CMD="version"
|
||||
;;
|
||||
--debug)
|
||||
_USE_DEBUG=1
|
||||
;;
|
||||
--auto-sudo|--sudo)
|
||||
_AUTO_SUDO=1
|
||||
;;
|
||||
*)
|
||||
# The first non-option argument is assumed to be the command name.
|
||||
# All subsequent arguments are added to $_COMMAND_ARGV.
|
||||
if [[ -n "${_CMD:-}" ]]
|
||||
then
|
||||
_COMMAND_ARGV+=("${__opt}")
|
||||
else
|
||||
_CMD="${__opt}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Set $_COMMAND_PARAMETERS to $_COMMAND_ARGV, minus the initial element, $0. This
|
||||
# provides an array that is equivalent to $* and $@ within each command
|
||||
# function, though the array is zero-indexed, which could lead to confusion.
|
||||
#
|
||||
# Use `unset` to remove the first element rather than slicing (e.g.,
|
||||
# `_COMMAND_PARAMETERS=("${_COMMAND_ARGV[@]:1}")`) because under bash 3.2 the
|
||||
# resulting slice is treated as a quoted string and doesn't easily get coaxed
|
||||
# into a new array.
|
||||
_COMMAND_PARAMETERS=("${_COMMAND_ARGV[@]}")
|
||||
unset "_COMMAND_PARAMETERS[0]"
|
||||
|
||||
_debug printf \
|
||||
"\${_CMD}: %s\\n" \
|
||||
"${_CMD}"
|
||||
_debug printf \
|
||||
"\${_RAW_OPTIONS} (one per line):\\n%s\\n" \
|
||||
"${_RAW_OPTIONS}"
|
||||
_debug printf \
|
||||
"\${_COMMAND_ARGV[*]}: %s\\n" \
|
||||
"${_COMMAND_ARGV[*]}"
|
||||
_debug printf \
|
||||
"\${_COMMAND_PARAMETERS[*]:-}: %s\\n" \
|
||||
"${_COMMAND_PARAMETERS[*]:-}"
|
||||
|
||||
###############################################################################
|
||||
# Environment
|
||||
###############################################################################
|
||||
@ -331,7 +238,7 @@ _main() {
|
||||
if _contains "${_CMD}" "${_DEFINED_COMMANDS[*]:-}"
|
||||
then
|
||||
# Pass all comment arguments to the program except for the first ($0).
|
||||
${_CMD} "${_COMMAND_PARAMETERS[@]:-}"
|
||||
"${_CMD}" "${_COMMAND_PARAMETERS[@]:-}"
|
||||
else
|
||||
_die printf "Unknown command: %s\\n" "${_CMD}"
|
||||
fi
|
||||
@ -1478,6 +1385,120 @@ unblock() {
|
||||
done
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Options
|
||||
#
|
||||
# NOTE: The `getops` builtin command only parses short options and BSD `getopt`
|
||||
# does not support long arguments (GNU `getopt` does), so the most portable
|
||||
# and clear way to parse options is often to just use a `while` loop.
|
||||
#
|
||||
# For a pure bash `getopt` function, try pure-getopt:
|
||||
# https://github.com/agriffis/pure-getopt
|
||||
#
|
||||
# More info:
|
||||
# http://wiki.bash-hackers.org/scripting/posparams
|
||||
# http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
||||
# http://stackoverflow.com/a/14203146
|
||||
# http://stackoverflow.com/a/7948533
|
||||
# https://stackoverflow.com/a/12026302
|
||||
# https://stackoverflow.com/a/402410
|
||||
###############################################################################
|
||||
|
||||
# Get raw options for any commands that expect them.
|
||||
_RAW_OPTIONS="${*:-}"
|
||||
|
||||
# Parse Options ###############################################################
|
||||
|
||||
# Initialize $_COMMAND_ARGV array
|
||||
#
|
||||
# This array contains all of the arguments that get passed along to each
|
||||
# command. This is essentially the same as the program arguments, minus those
|
||||
# that have been filtered out in the program option parsing loop. This array
|
||||
# is initialized with $0, which is the program's name.
|
||||
_COMMAND_ARGV=("${0}")
|
||||
# Initialize $_CMD and `$_USE_DEBUG`, which can continue to be blank depending
|
||||
# on what the program needs.
|
||||
_CMD=""
|
||||
_USE_DEBUG=0
|
||||
_AUTO_SUDO=0
|
||||
|
||||
_SUBCOMMANDS=(
|
||||
add
|
||||
backups
|
||||
block
|
||||
commands
|
||||
disable
|
||||
disabled
|
||||
edit
|
||||
enable
|
||||
enabled
|
||||
file
|
||||
help
|
||||
list
|
||||
remove
|
||||
search
|
||||
show
|
||||
unblock
|
||||
version
|
||||
)
|
||||
_SUBCOMMANDS_PATTERN="$(_join '|' "${_SUBCOMMANDS[@]}")"
|
||||
|
||||
while [[ ${#} -gt 0 ]]
|
||||
do
|
||||
__opt="${1}"
|
||||
|
||||
shift
|
||||
|
||||
case "${__opt}" in
|
||||
-h|--help)
|
||||
_CMD="help"
|
||||
;;
|
||||
--version)
|
||||
_CMD="version"
|
||||
;;
|
||||
--debug)
|
||||
_USE_DEBUG=1
|
||||
;;
|
||||
--auto-sudo|--sudo)
|
||||
_AUTO_SUDO=1
|
||||
;;
|
||||
*)
|
||||
# The first non-option argument is assumed to be the command name.
|
||||
# All subsequent arguments are added to $_COMMAND_ARGV.
|
||||
if [[ -z "${_CMD:-}" ]] && [[ "${__opt:-}" =~ ${_SUBCOMMANDS_PATTERN} ]]
|
||||
then
|
||||
_CMD="${__opt}"
|
||||
else
|
||||
_COMMAND_ARGV+=("${__opt}")
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Set $_COMMAND_PARAMETERS to $_COMMAND_ARGV, minus the initial element, $0. This
|
||||
# provides an array that is equivalent to $* and $@ within each command
|
||||
# function, though the array is zero-indexed, which could lead to confusion.
|
||||
#
|
||||
# Use `unset` to remove the first element rather than slicing (e.g.,
|
||||
# `_COMMAND_PARAMETERS=("${_COMMAND_ARGV[@]:1}")`) because under bash 3.2 the
|
||||
# resulting slice is treated as a quoted string and doesn't easily get coaxed
|
||||
# into a new array.
|
||||
_COMMAND_PARAMETERS=("${_COMMAND_ARGV[@]}")
|
||||
unset "_COMMAND_PARAMETERS[0]"
|
||||
|
||||
_debug printf \
|
||||
"\${_CMD}: %s\\n" \
|
||||
"${_CMD}"
|
||||
_debug printf \
|
||||
"\${_RAW_OPTIONS} (one per line):\\n%s\\n" \
|
||||
"${_RAW_OPTIONS}"
|
||||
_debug printf \
|
||||
"\${_COMMAND_ARGV[*]}: %s\\n" \
|
||||
"${_COMMAND_ARGV[*]}"
|
||||
_debug printf \
|
||||
"\${_COMMAND_PARAMETERS[*]:-}: %s\\n" \
|
||||
"${_COMMAND_PARAMETERS[*]:-}"
|
||||
|
||||
###############################################################################
|
||||
# Run Program
|
||||
###############################################################################
|
||||
|
Loading…
Reference in New Issue
Block a user