@@ -0,0 +1,101 @@
#! /usr/bin/env bash
# Time-stamp: <2017-04-27 09:57:21 kmodi>
# Time-stamp: <2018-03-20 12:58:02 bobpaul>
# derived from kmodi's gist: https://gist.github.com/kaushalmodi/74e9875d5ab0a2bc1010447f1bee5d0a
#
# Example of using getopt to parse command line options
# http://stackoverflow.com/a/29754866/1219634 Limitation: All the options
# starting with - have to be listed in --options/--longoptions, else getopt will
# error out.
# The downside is that if you intend to use this as a wrapper to some other program,
# arguments you want to pass on to that program must come after a -- argument.
# ex: mygrep --myoption mypositional -- -r 'options_for_real_grep' *
getopt --test 2> /dev/null
if [[ $? -ne 4 ]]; then
echo " GNU's enhanced getopt is required to run this script"
echo " You can usually find this in the util-linux package"
echo " On MacOS/OS X see homebrew's package: http://brewformulas.org/Gnu-getopt"
echo " For anyone else, build from source: http://frodo.looijaard.name/project/getopt"
exit 1
fi
# bash strict mode: see http://redsymbol.net/articles/unofficial-bash-strict-mode/ for info
set -euo pipefail
IFS=$' \n\t '
# Initialize variables
HELP=0
DEBUG=0
VERBOSE=0
declare -a EXTRA_ARGS
declare -a POSITIONAL
DISCARD_OPTS_AFTER_DOUBLEDASH=0 # 1=Discard, 0=Save opts after -- to ${EXTRA_ARGS}
echo " All pre-getopt arguments: $@ "
# An option followed by a single colon ':' means that it *needs* an argument.
# An option followed by double colons '::' means that its argument is optional.
# See `man getopt'.
SHORT=-hDvo: # List all the short options
LONG=help,debug,verbose,outfile: # List all the long options
# - Temporarily store output to be able to check for errors.
# - Activate advanced mode getopt quoting e.g. via "--options".
# - Pass arguments only via -- "$@" to separate them correctly.
# - getopt auto-adds "--" at the end of ${PARSED}, which is then later set to
# "$@" using the set command.
PARSED=$( getopt --options ${SHORT} \
--longoptions ${LONG} \
--name " $0 " \
-- " $@ " ) # Pass all the args to this script to getopt
if [[ $? -ne 0 ]]; then
# e.g. $? == 1
# then getopt has complained about wrong arguments to stdout
exit 2
fi
# Use eval with "$PARSED" to properly handle the quoting
# The set command sets the list of arguments equal to ${PARSED}.
eval set -- " ${PARSED} "
echo " Getopt parsed arguments: ${PARSED} "
echo " Effective arguments: $@ "
echo " Num args: $# "
dashes=0 # flag to track if we've parsed '--'
while [[ $# -gt 0 ]]; do
echo " parsing arg: $1 "
case " $1 " in
-o|--outfile) shift
OUT_FILE=" $1 " ;;
-h|--help) HELP=1;;
-D|--debug) DEBUG=1;;
-v|--verbose) VERBOSE=1;;
--) dashes=1
if [[ ${DISCARD_OPTS_AFTER_DOUBLEDASH} -eq 1 ]]; then break ; fi
;;
* ) # store positional arguments until we reach the dashes, then store as extra
if [[ $dashes -eq 0 ]]; then POSITIONAL+=(" $1 " );
else EXTRA_ARGS+=(" $1 " ); fi
;;
esac
shift # Expose the next argument
done
set -- " ${POSITIONAL[@]} "
echo " "
echo " "
echo " Parsed options:"
echo " help: ${HELP} , debug: ${DEBUG} , verbose: ${VERBOSE} , outfile: ${OUT_FILE:- } "
# restore positional arguments as $1, $2, etc
echo " Listing positional arguments:"
while [[ $# -gt 0 ]]; do
# here's where you can parse your positional arguments
echo " $1 "
shift
done
echo " Extra arguments: (those after --)"
for i in ${! EXTRA_ARGS[@]} ; do
# here's the extra args you can pass to a wrapped utility
echo " ${EXTRA_ARGS[$i]} "
done