在 Bash 函数中使用 getopts

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16654607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:44:30  来源:igfitidea点击:

Using getopts inside a Bash function

bashfunctiongetopts

提问by Magnus

I'd like to use getoptsinside a function that I have defined in my .bash_profile. The idea is I'd like to pass in some flags to this function to alter its behavior.

我想getopts在我在 .bash_profile 中定义的函数中使用。这个想法是我想将一些标志传递给这个函数来改变它的行为。

Here's the code:

这是代码:

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

When I invoke it like this:

当我像这样调用它时:

t -a bc

I get this output:

我得到这个输出:

-a bc
?
?

What's wrong? I'd like to get the value bcwithout manually shifting and parsing. How do I use getoptscorrectly inside a function?

怎么了?我想在bc不手动移动和解析的情况下获得该值。如何getopts在函数内部正确使用?

EDIT: corrected my code snippet to try $OPTARG, to no avail

编辑:更正了我的代码片段以尝试 $OPTARG,但无济于事

EDIT #2: OK turns out the code is fine, my shell was somehow messed up. Opening a new window solved it. The arg value was indeed in $OPTARG.

编辑 #2:好的,结果代码很好,我的外壳不知何故搞砸了。打开一个新窗口解决了它。arg 值确实在 $OPTARG 中。

回答by Adrian Frühwirth

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

正如@Ansgar 指出的那样,您的选项的参数存储在 中${OPTARG},但这并不是在getopts函数内部使用时唯一需要注意的事情。您还需要${OPTIND}通过取消设置或声明它来确保该函数是本地的local,否则在多次调用该函数时会遇到意外行为。

t.sh:

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:

如果你注释掉# local OPTIND,这就是你得到的:

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

除此之外,它的用法与在函数外使用时相同。

回答by kenorb

Here is simple example of getoptsusage within shell function:

以下是getoptsshell 函数中的简单用法示例:

#!/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 OPTINDautomatically between multiple calls to getopts(man bash).

正如@Adrian 指出的那样local OPTIND(或OPTIND=1)需要设置为 shell 不会OPTIND多次调用getopts( man bash)之间自动重置。

The base-syntax for getoptsis:

的基本语法getopts是:

getopts OPTSTRING VARNAME [ARGS...]

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

默认情况下,不指定参数等效于使用“$@”显式调用它,即:getopts "a:" opts "$@"

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

如果出现问题,这些是用于getopts检查的变量:

  • 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.
  • OPTIND- 要处理的下一个参数的索引,
  • OPTARG- 变量设置为由getopts,找到的选项的任何参数
  • OPTERR(不是 POSIX) - 设置为 0 或 1 以指示 Bash 是否应显示由getopts.

Further more, see: Small getopts tutorialat The Bash Hackers Wiki

更多信息,请参阅:The Bash Hackers Wiki 上的Small getopts 教程

回答by Ansgar Wiechers

The argument is stored in the varable $OPTARG.

参数存储在变量中$OPTARG

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

Output:

输出:

$ t -a bc
-a bc
a
bc