Source code in KshOptionParsing.sh

To see how this is used return to this tutorial index.

#!/bin/ksh -u
# How to process 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: @(#)KshOptionParsing	1.3 07/01/15 16:11:20
# Author: Alain D D Williams, addw@phcomp.co.uk, 2009


PROGNAME=${0##*/}

Verbose=0

# Print the message to what used to be stderr AND current stderr and exit.
# Do not call this unt
function Die {
	echo "$PROGNAME: $*" >&2
	exit 2
}

# Generate a note that will be seen by the user -- even if redirected
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
	cat <<-!
		This program does X Y Z
		Usage: $PROGNAME [-opts] [files ...]
		-d, --dee	Something that takes an argument
		-v, --verb	Verbose (multiple use gives more verbosity)
		-x, --help	eXplain
		Version: 1.3 07/01/15
		!
	exit $#
}

# Set for every long option: 1 needs arg; 0 doesn't:
OPThelp=0 OPTverb=0 OPTdee=1

# Parse options, recognise --long options
while	[[ $# -ge $OPTIND ]] && eval A=\${$OPTIND} || A=
	if [[ $A == --* ]]	# Long option ?
	then	(( OPTIND++ ))
		opt=${A#--}
		[[ $opt == *=* ]] && OPTARG=${opt#*=} && opt=${opt%=*} || OPTARG=
		if eval [[ -n \${OPT$opt:-} ]]					# Known long option ?
		then	if eval [[ \$OPT$opt == 1 ]]
			then	if [[ $A != *=* ]]				# Want argument, use next
				then	if (( $OPTIND > $# ))
					then	OPTARG=$opt			# None
						opt=:
					else	eval OPTARG=\${$OPTIND}
						(( OPTIND++ ))
					fi
				fi
			else	[[ $A == *=* ]] && OPTARG=$opt && opt=::	# Should not have arg
			fi
		else	OPTARG=$opt						# Unrecognised option
			opt=?
		fi
		true
	else	getopts :d:vx opt
	fi
do	case "$opt" in
	d|dee)	echo "Dee arg=$OPTARG" ;;
	v|verb)	(( Verbose++ )) ;;
	x|help)	Usage ;;
	::)	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: $#"
[[ $# -ge 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"
done

# end

Return to this tutorial index.