To see how this is used return to this tutorial index.
#!/bin/ksh -u
# How to process short & long options in the shell.
#
# This works with:
# * the Korn shell:
# pdksh -- a clone of the Korn shell (ksh)
# KSH-93 -- the KornShell by David Korn of AT&T Bell Laboratories.
# * bash, not sure which versions
# **** Shell Script Template ****
# SCCS: @(#) 1.6 10/21/21 13:44:39
# Author: Alain D D Williams, addw@phcomp.co.uk, 2009, 2021
PROGNAME=${0##*/}
Verbose=0
Quiet=0
# Print the message to stderr and exit.
function Die {
echo "$PROGNAME: $*" >&2
exit 2
}
# Generate a note that will be seen by the user, ie sent to stderr -- even if stdout redirected
# Only if Verbose
function Note {
(( Verbose > 0 )) && echo "$PROGNAME: $*" >&2
}
# Print a usage message & exit the program.
# If an argument is given print that as an error and exit 1
function Usage {
(( $# > 0 )) && echo "$PROGNAME: $*" >&2
sed -e 's/^^//' <<-!
This program does X Y Z
Usage: $PROGNAME [-opts] [files ...]
--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
^ Quiet - say a bit less than usual about what is happening.
-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 '--'.
Version: 1.6 10/21/21
!
exit $#
}
# Long Options, value: 0 - no argument, 1 - required argument, 2 - optional argument
typeset -A LongOpts=([help]=0 [verb]=0 [na]=1 [oa]=2)
# Single letter options, a ':' after option means it takes an argument. See: man ksh -- look for getopts.
ShortOpts=:d:qvx
# Parse options, recognise --long 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
d|dee) echo "Dee arg=$OPTARG" ;;
v|verb) (( Verbose++ )) ;;
q|quiet)Quiet=1 ;;
x|help) Usage ;;
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 ;;
::) 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"
echo "End opts processing - OPTIND=$OPTIND, #args: $#"
(( $# >= 1 )) && echo "Args are: $@"
# Now process the arguments as files:
for file
do Note "Processing $file"
# Do something
[[ -f $file ]] && ls -l $file || Die "Cannot see file $file"
done
# end
Return to this tutorial index.