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.

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

Enjoyed this article? Please like it or share it.

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