User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

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>:<long_opt>?<description>]<value_type>[<value_name>:=<default_value>]

<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.

Attachments:
Download this file (foobar_getopts.zip)foobar_getopts.zip1 kB

Add comment

Please connect with one of social login below (or fill up name and email)

     


Security code
Refresh

Comments   

MdS
# More documentationMdS 2021-07-06 22:01
Hi,

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
Reply | Reply with quote | Quote
Paolo
# also worksPaolo 2020-01-03 09:41
I've checked and on ksh (93) version 93t+ (ksh93 --version output: version sh (AT&T Research) 93t+ 2009-05-01) running on IBM AIX 7.1.5 it works as expected :-)
Reply | Reply with quote | Quote
lieven
# Is there a way to introduce new lines in description?lieven 2018-06-26 00:51
I have added new lines in the description with this type of instruction:
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?
Reply | Reply with quote | Quote
Alina
# Getopts with man page and long optionsAlina 2016-11-17 16:31
J’aі découvert votre sitye blog suг Goolgle et cοnsulter quelques-uns de vos premier
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!
Reply | Reply with quote | Quote