处理标志和可选参数

内置的 getopts 可以在函数内部用于编写容纳标志和可选参数的函数。这没有特别的困难,但是必须适当地处理 getopts 所触及的值。作为一个例子,我们定义了一个 failwith 函数,它在 stderr 上写入消息并以代码 1 或作为参数提供给 -x 选项的任意代码退出:

# failwith [-x STATUS] PRINTF-LIKE-ARGV
#  Fail with the given diagnostic message
#
# The -x flag can be used to convey a custom exit status, instead of
# the value 1.  A newline is automatically added to the output.

failwith()
{
    local OPTIND OPTION OPTARG status

    status=1
    OPTIND=1

    while getopts 'x:' OPTION; do
        case ${OPTION} in
            x)    status="${OPTARG}";;
            *)    1>&2 printf 'failwith: %s: Unsupported option.\n' "${OPTION}";;
        esac
    done

    shift $(( OPTIND - 1 ))
    {
        printf 'Failure: '
        printf "$@"
        printf '\n'
    } 1>&2
    exit "${status}"
}

该功能可以如下使用:

failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'

等等。

请注意,对于 printf ,变量不应该用作第一个参数。如果要打印的消息由变量的内容组成,则应使用%s 说明符打印它,如

failwith '%s' "${message}"