Source code in Skeleton.sh

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

# Try this out by running:
#	ksh -u Skeleton.sh --na=SomeArgument --oa --oa=OptionalArgument a b c

# SCCS: @(#)Skeleton.sh	1.4 07/01/15 16:11:29

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
	[[ $# -gt 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
	--oa[=arg]
	^	A long option that has an optional argument
	-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.4 07/01/15
	!
	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	[[ $# -ge $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:
		if [[ -z ${LongOpts[$opt]:-} ]]
		then	OPTARG=$opt && opt='?'
		else	[[ $hasArg = 0 && ${LongOpts[$opt]} = 1 ]] && OPTARG=$opt && opt=:
			[[ $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.