Using getopts inside a Bash function

偶尔善良 提交于 2019-11-27 00:19:49

As @Ansgar points out, the argument to your option is stored in ${OPTARG}, but this is not the only thing to watch out for when using getopts inside a function. You also need to make sure that ${OPTIND} is local to the function by either unsetting it or declaring it local, otherwise you will encounter unexpected behaviour when invoking the function multiple times.

t.sh:

#!/bin/bash

foo()
{
    foo_usage() { echo "foo: [-a <arg>]" 1>&2; exit; }

    local OPTIND o a
    while getopts ":a:" o; do
        case "${o}" in
            a)
                a="${OPTARG}"
                ;;
            *)
                foo_usage
                ;;
        esac
    done
    shift $((OPTIND-1))

    echo "a: [${a}], non-option arguments: $*"
}

foo
foo -a bc bar quux
foo -x

Example run:

$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
foo: [-a <arg>]

If you comment out # local OPTIND, this is what you get instead:

$ ./t.sh
a: [], non-option arguments:
a: [bc], non-option arguments: bar quux
a: [bc], non-option arguments:

Other than that, its usage is the same as when used outside of a function.

kenorb

Here is simple example of getopts usage within shell function:

#!/usr/bin/env bash
t() {
  local OPTIND
  getopts "a:" OPTION
  echo Input: $*, OPTION: $OPTION, OPTARG: $OPTARG
}
t "$@"
t -a foo

Output:

$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo

As @Adrian pointed out, local OPTIND (or OPTIND=1) needs to be set as shell does not reset OPTIND automatically between multiple calls to getopts (man bash).

The base-syntax for getopts is:

getopts OPTSTRING VARNAME [ARGS...]

and by default, not specifying arguments is equivalent to explicitly calling it with "$@" which is: getopts "a:" opts "$@".

In case of problems, these are the used variables for getopts to check:

  • OPTIND - the index to the next argument to be processed,
  • OPTARG - variable is set to any argument for an option found by getopts,
  • OPTERR (not POSIX) - set to 0 or 1 to indicate if Bash should display error messages generated by the getopts.

Further more, see: Small getopts tutorial at The Bash Hackers Wiki

The argument is stored in the varable $OPTARG.

function t() {
  echo $*
  getopts "a:" OPTION
  echo $OPTION
  echo $OPTARG
}

Output:

$ t -a bc
-a bc
a
bc
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!