Created
April 27, 2017 14:06
-
-
Save kaushalmodi/74e9875d5ab0a2bc1010447f1bee5d0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Time-stamp: <2017-04-27 09:57:21 kmodi> | |
# | |
# 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. So this cannot be used in wrapper scripts for other applications | |
# where you plan to pass on the non-wrapper-script options to that wrapped | |
# application. | |
# Initialize variables | |
help=0 | |
debug=0 | |
verbose=0 | |
dummy_arg="__dummy__" | |
extra_args=("${dummy_arg}") # Because set -u does not allow undefined variables to be used | |
discard_opts_after_doubledash=0 # 1=Discard, 0=Save opts after -- to ${extra_args} | |
echo "All pre-getopt arguments: $*" | |
getopt --test > /dev/null | |
if [[ $? -ne 4 ]]; then | |
echo "I'm sorry, 'getopt --test' failed in this environment." | |
exit 1 | |
fi | |
# 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,output: # 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: $#" | |
while [[ ( ${discard_opts_after_doubledash} -eq 1 ) || ( $# -gt 0 ) ]] | |
do | |
echo "parsing arg: $1" | |
case "$1" in | |
-o|--output) shift | |
out_file="$1";; | |
-h|--help) help=1;; | |
-D|--debug) debug=1;; | |
-v|--verbose) verbose=1;; | |
--) if [[ ${discard_opts_after_doubledash} -eq 1 ]]; then break; fi;; | |
*) extra_args=("${extra_args[@]}" "$1");; | |
esac | |
shift # Expose the next argument | |
done | |
# Now delete the ${dummy_arg} from ${extra_args[@]} array # http://stackoverflow.com/a/16861932/1219634 | |
extra_args=("${extra_args[@]/${dummy_arg}}") | |
echo "help: ${help}, debug: ${debug}, verbose: ${verbose}, in: $1, out: $out_file, extra args=${extra_args[*]}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This puts all positional arguments, even those before the
--
into extra args. The intention ofin: $1
on the final line is unclear to me as$1
is always undefined by this point.I've made an update to address these concerns, as well as some minor cleanup (like using
declare
for lists rather than dummy_arg).