To see how this is used return to this tutorial index.
#!/bin/ksh -u
# This is a skeleton shell script with long argument processing.
# Copyright (c) Alain D D Williams <addw@phcomp.co.uk> January 2012-2020
# It is expected that you will modify this skeleton for your own use.
# This code is released as free software under the BSD 3 clause license:
# https://directory.fsf.org/wiki/License:BSD-3-Clause
# Try this out by running:
# ksh -u Skeleton.sh --na=SomeArgument --oa --oa=OptionalArgument a b c
# This also works with modern versions of bash
# SCCS: @(#)Skeleton.sh 1.7 10/26/20 13:44:59
PROGNAME=${0##*/}
function Die {
echo "$PROGNAME: $*" >&2
exit 2
}
# Generate a note in verbose mode
# If the first arg is a digit, only log if $verbose is at least that number.
function Note {
typeset -i level=1
(( $# > 1 )) && [[ $1 == [0-9] ]] && level=$1 && shift
(( verbose < level )) && return
echo "$*" >&2
}
# Log to user & file, unless quiet.
# If option '-b' put a blank line out first.
function Log {
(( quiet == 1 )) && return
echo "$PROGNAME: $*" >&2
}
# Generate a usage message and exit. If there is an argument print it and exit code is 2
function Usage {
(( $# > 0 )) && echo "$PROGNAME: $*" >&2 && ec=2 || ec=0
sed -e 's/^^//' <<-!
Description ... blah, blah
Usage: $PROGNAME [-opts] [files]
-h --help
^ Help message
--na=arg
^ A long option that needs an argument
^ Can use space instead of '=': --na arg
--oa[=arg]
^ A long option that has an optional argument
^ Here the '=' cannot be replaced by a space
-q --quiet
^ Don't complain about non errors
-v Verbose - say a bit more than usual about what is happening.
^ Give this more than once for increased verbosity.
- -- Denotes the end of the options. Arguments after this will be handled as file names
^ even if they start with a '-'.
^ This may either be a '-' or '--'.
More words
Version: 1.7 10/26/20
!
exit $ec
}
# **** Start ****
verbose=0
quiet=0
# Long Options, value: 0 - no argument, 1 - required argument, 2 - optional argument
typeset -A LongOpts=([help]=0 [quiet]=0 [na]=1 [oa]=2)
ShortOpts=:hqv
# Parse options, recognise --options
while (( $# >= $OPTIND )) && eval opt=\${$OPTIND} || break
[[ $opt == - ]] && shift && break
if [[ $opt == --?* ]]
then opt=${opt#--}
shift
# Argument to option ?
[[ $opt == *=* ]] && OPTARG=${opt#*=} && opt=${opt%=$OPTARG} && hasArg=1 || typeset OPTARG= hasArg=0
# Check if known option and if it has an argument if it must have one:
if [[ -z ${LongOpts[$opt]:-} ]]
then OPTARG=$opt && opt='?'
else if [[ $hasArg = 0 && ${LongOpts[$opt]} = 1 ]]
then # Required argument. Can grab next arg ?
if (( $# >= $OPTIND ))
then OPTARG=$1 && shift
else OPTARG=$opt && opt=:
fi
fi
[[ $hasArg = 1 && ${LongOpts[$opt]} = 0 ]] && OPTARG=$opt && opt=::
fi
true # for the while
else getopts $ShortOpts opt
fi
do case "$opt" in
h|help) Usage ;;
q|quiet)quiet=1 ;;
na) echo "Option --na has the argument that it needs: '$OPTARG'" ;;
oa) if [[ $hasArg = 1 ]]
then echo "Option --oa has optional argument: '$OPTARG'"
else echo "Option --oa does not have an optional argument"
fi ;;
v) (( verbose++ )) ;;
::) Usage "Unexpected argument to option '$OPTARG'" ;;
:) Usage "Missing argument to option '$OPTARG'" ;;
\?) Usage "Unknown option '$OPTARG'" ;;
*) Usage "Internal program error, unrecognised argument '$opt'" ;;
esac
done
shift $(( OPTIND - 1 ))
echo "verbose=$verbose quiet=$quiet"
for a
do echo "arg='$a'"
done
# end
Return to this tutorial index.