Skip to content

Instantly share code, notes, and snippets.

@hoylen
Last active July 23, 2020 11:59
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save hoylen/6607180 to your computer and use it in GitHub Desktop.
Save hoylen/6607180 to your computer and use it in GitHub Desktop.
Portable getopt argument processing in shell scripts. Detects which version of getopt is installed. When available, it uses GNU enhanced getopt to support long option names and whitespaces in arguments. Otherwise, defaults to using the original getopt.
#!/bin/sh
#
# Example showing use of getopt detection and use of GNU enhanced getopt
# to handle arguments containing whitespace.
#
# Written in 2004 by Hoylen Sue <hoylen@hoylen.com>
#
# To the extent possible under law, the author(s) have dedicated all copyright and
# related and neighboring rights to this software to the public domain worldwide.
# This software is distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication along with this software.
# If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
PROG=`basename $0`
VERSION=0.1
# Remove this trap if you are doing your own error detection or don't care about errors
trap "echo $PROG: error encountered: aborted; exit 3" ERR
#----------------------------------------------------------------
# Process command line arguments
## Define options: trailing colon means has an argument (customize this: 1 of 3)
SHORT_OPTS=o:vh
LONG_OPTS=output:,verbose,version,help
SHORT_HELP="Usage: $PROG [options] arguments
Options:
-o file output file name
-v show extra information
-h show this help message"
LONG_HELP="Usage: $PROG [options] arguments
Options:
-o | --output file output file name
-v | --verbose show extra information
-h | --help show this help message
--version show version information"
# Detect if GNU Enhanced getopt is available
HAS_GNU_ENHANCED_GETOPT=
if getopt -T >/dev/null; then :
else
if [ $? -eq 4 ]; then
HAS_GNU_ENHANCED_GETOPT=yes
fi
fi
# Run getopt (runs getopt first in `if` so `trap ERR` does not interfere)
if [ -n "$HAS_GNU_ENHANCED_GETOPT" ]; then
# Use GNU enhanced getopt
if ! getopt --name "$PROG" --long $LONG_OPTS --options $SHORT_OPTS -- "$@" >/dev/null; then
echo "$PROG: usage error (use -h or --help for help)" >&2
exit 2
fi
ARGS=`getopt --name "$PROG" --long $LONG_OPTS --options $SHORT_OPTS -- "$@"`
else
# Use original getopt (no long option names, no whitespace, no sorting)
if ! getopt $SHORT_OPTS "$@" >/dev/null; then
echo "$PROG: usage error (use -h for help)" >&2
exit 2
fi
ARGS=`getopt $SHORT_OPTS "$@"`
fi
eval set -- $ARGS
## Process parsed options (customize this: 2 of 3)
while [ $# -gt 0 ]; do
case "$1" in
-o | --output) OUTFILE="$2"; shift;;
-v | --verbose) VERBOSE=yes;;
-h | --help) if [ -n "$HAS_GNU_ENHANCED_GETOPT" ]
then echo "$LONG_HELP";
else echo "$SHORT_HELP";
fi; exit 0;;
--version) echo "$PROG $VERSION"; exit 0;;
--) shift; break;; # end of options
esac
shift
done
## Process remaining arguments and use options (customize this: 3 of 3)
echo "$PROG: DEBUG: option VERBOSE: $VERBOSE"
echo "$PROG: DEBUG: option OUTFILE: $OUTFILE"
if [ $# -gt 0 ]; then
for ARG in "$@"; do
echo "$PROG: DEBUG: argument: $ARG"
done
fi
#EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment