mirror of
https://github.com/octoleo/hosts.git
synced 2025-01-06 07:30:42 +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 "${@}"
|
_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
|
# Environment
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -331,7 +238,7 @@ _main() {
|
|||||||
if _contains "${_CMD}" "${_DEFINED_COMMANDS[*]:-}"
|
if _contains "${_CMD}" "${_DEFINED_COMMANDS[*]:-}"
|
||||||
then
|
then
|
||||||
# Pass all comment arguments to the program except for the first ($0).
|
# Pass all comment arguments to the program except for the first ($0).
|
||||||
${_CMD} "${_COMMAND_PARAMETERS[@]:-}"
|
"${_CMD}" "${_COMMAND_PARAMETERS[@]:-}"
|
||||||
else
|
else
|
||||||
_die printf "Unknown command: %s\\n" "${_CMD}"
|
_die printf "Unknown command: %s\\n" "${_CMD}"
|
||||||
fi
|
fi
|
||||||
@ -1478,6 +1385,120 @@ unblock() {
|
|||||||
done
|
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
|
# Run Program
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
Loading…
Reference in New Issue
Block a user