In recent Korn Shell ksh93, getopts
can be more powerful than you think, it can :
- naturally parse short and long options with error management
- manage option value as optional, as mandatory or as numeric
- auto generate man page alike
This article will show how to use getopts
in recent ksh93. If you have older ksh, read this other article instead.
(foobar_getopts.ksh zip file attachement in this article)
This script has been tested on ...
... Oracle Linux 7
... /bin/ksh --version #sh (AT&T Research) 93u+ 2012-08-01
foobar_getopts.ksh source code
foobar_getopts.ksh is a script example to show how to use getopts
with short/long options in recent ksh93.
This script is also available for download at the end of the article.
#!/bin/ksh
#============================
# SET VARIABLES
#============================
unset SCRIPT_OPTS SCRIPT_ARGS USAGE
#== script info ==#
SCRIPT_VERS="0.0.1"
SCRIPT_AUTH="Michel VONGVILAY (www.uxora.com)"
SCRIPT_NAME="$(basename ${0})"
SCRIPT_TITL="foobar getopts example"
SCRIPT_DESC="this script is a example to show how to "
SCRIPT_DESC+="use getopts with short and long options."
#== script options ==#
SCRIPT_OPTS+="[f:foo?Set foo setting (default).]"
SCRIPT_OPTS+="[b:bar?Set bar setting.]"
SCRIPT_OPTS+="[B:barfoo]#[n:=2?Set barfoo to number n.]{
[0-5?low number]
[6-10?high number]
}"
SCRIPT_OPTS+="[F:foobar?Set foobar and foobar_name.]:?[name]"
SCRIPT_ARGS+=$'\n\nfiles ...\n\n'
#== program variables ==#
foo=1 bar=0
barfoo=2 foobar=0
foobar_name=
#============================
# OPTIONS WITH GETOPTS
#============================
#== set usage ==#
USAGE=$'[-?\n@(#)$Id: '${SCRIPT_NAME}' '${SCRIPT_VERS}$' $\n]'
USAGE+="[-author?${SCRIPT_AUTH}]"
USAGE+="[-copyright?www.uxora.com]"
USAGE+="[-license?GNU General Public License]"
USAGE+="[+NAME?${SCRIPT_NAME} - ${SCRIPT_TITL}]"
USAGE+="[+DESCRIPTION?${SCRIPT_DESC}]"
USAGE+="${SCRIPT_OPTS}"
USAGE+="${SCRIPT_ARGS}"
USAGE+=$'[+SEE ALSO?\awww.uxora.com\a]'
#== parse options ==#
while getopts "$USAGE" optchar ; do
case $optchar in
f) foo=1 bar=0 ;;
b) foo=0 bar=1 ;;
B) barfoo=${OPTARG}
[[ barfoo -lt 0 ]] && barfoo=0
[[ barfoo -gt 10 ]] && barfoo=10
;;
F) foobar=1
[[ "${OPTARG}" == "0" ]] && OPTARG=
foobar_name=${OPTARG:-"NOT_SET"}
;;
esac
done
shift $((${OPTIND} - 1))
#============================
# MAIN SCRIPT
#============================
#== print variables ==#
print foo=$foo bar=$bar
print barfoo=$barfoo
print foobar=$foobar foobar_name=$foobar_name
print files=$@
How to define an option
In this script, options are defined in #== script options ==#
part with SCRIPT_OPTS
variable as follow:
<short_opt> | One letter for short option |
<long_opt> | String for long option |
<description> | Option text description |
<value_type> | Use : for options that require a value. Use # for options that require a numeric value. Use :? and #? for options that allow value but not require. |
<value_name> | name of the value |
<default_value> | value by default |
Extra description can be added within {
and }
as it is done for barfoo
option :
SCRIPT_OPTS+="[B:barfoo]#[n:=2?Set barfoo to number n.]{
[0-5?low number]
[6-10?high number]
}"
How to display help and man
getopts
has already some predefined options :
-?
display short usage --help
display usage --man
display full man page
And for some more specific information, these predefined options:
--about
display version, author,copyright and licence information --version
display version only --author
display author only --copyright
display copyright only --license
display license only
# Display short help
$ ./foobar_getopts.ksh -?
<<--OUTPUT--
Usage: ./foobar_getopts.ksh [-fb] [-B n] [-F[name]] files ...
--OUTPUT--
# Display long help
$ ./foobar_getopts.ksh --help
<<--OUTPUT--
Usage: ./foobar_getopts.ksh [ options ] files ...
OPTIONS
-f, --foo Set foo setting (default).
-b, --bar Set bar setting.
-B, --barfoo=n Set barfoo to number n.
0-5 low number
6-10 high number
The default value is 2.
-F, --foobar[=name]
Set foobar and foobar_name. The option value may be omitted.
--OUTPUT--
# Display info and version
$ ./foobar_getopts.ksh --about
<<--OUTPUT--
version foobar_getopts.ksh 0.0.1
author Michel VONGVILAY (www.uxora.com)
copyright www.uxora.com
license GNU General Public License
--OUTPUT--
$ ./foobar_getopts.ksh --version
<<--OUTPUT--
version foobar_getopts.ksh 0.0.1
--OUTPUT--
# Display full man help
$ ./foobar_getopts.ksh --man
<<--OUTPUT--
NAME
foobar_getopts.ksh - foobar getopts example
SYNOPSIS
foobar_getopts.ksh [ options ] files ...
DESCRIPTION
this script is a example to show how to use getopts with short and long options.
OPTIONS
-f, --foo Set foo setting (default).
-b, --bar Set bar setting.
-B, --barfoo=n Set barfoo to number n.
0-5 low number
6-10 high number
The default value is 2.
-F, --foobar[=name]
Set foobar and foobar_name. The option value may be omitted.
SEE ALSO
www.uxora.com
IMPLEMENTATION
version foobar_getopts.ksh 0.0.1
author Michel VONGVILAY (www.uxora.com)
copyright www.uxora.com
license GNU General Public License
--OUTPUT--
Some examples
See how getopts
manage itself options errors :
# Unknown option error
$ ./foobar_getopts.ksh -x
<<--OUTPUT--
./foobar_getopts.ksh: -x: unknown option
Usage: ./foobar_getopts.ksh [-fb] [-B n] [-F[name]] files ...
--OUTPUT--
# barfoo option without argument
# Expected argument error
$ ./foobar_getopts.ksh -B
<<--OUTPUT--
./foobar_getopts.ksh: -B: numeric n argument expected
Usage: ./foobar_getopts.ksh [-fb] [-B n] [-F[name]] files ...
--OUTPUT--
Now see getopts
works without errors :
# foobar short option and barfoo short option
$ ./foobar_getopts.ksh -bF "Hello world" -B 6 file1 file2
<<--OUTPUT--
foo=0 bar=1
barfoo=6
foobar=1 foobar_name=Hello world
files=file1 file2
--OUTPUT--
# foobar short option without arg and barfoo long option
$ ./foobar_getopts.ksh -bF --barfoo 6 file1 file2
<<--OUTPUT--
foo=0 bar=1
barfoo=6
foobar=1 foobar_name=NOT_SET
files=file1 file2
--OUTPUT--
Better you test by yourself to see if it works and how it works.
Please leave comments and suggestions,
Michel.
Enjoyed this article? Please like it or share it.
Comments
I've been searching and I cannot find any documentation, I mean nothing about the "--man", "help" portion of this command in ksh93, ksh and BASH.
It's as if it was an undocumented feature.
I would like to know more about this.
Do you have anything to pass on?
Thanks
SCRIPT_DESC+=$'\nhave fun.'
When I echo "$USAGE", this generates new lines as intended.
But when I use the ./myscript --usage, all the text is collated.
Other formatting characters like \a on the other hand, do show in the --usage output
Any idea how I can format my description over several lines?
post. Ꮯontinuer de maintenir la très bonne opération. J’ɑjoute juste votre flkux RSS
à mon MSN lecteurr d’actualités. Désireuх de lire plus venant de vous parг la suite!
RSS feed for comments to this post