在Bash函数中使用getopts

我想在.bash_profile中定义的函数中使用bc。我的想法是我想向该函数传递一些标志以更改其行为。

这是代码:

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

当我这样调用它时:

t -a bc

我得到以下输出:

-a bc
?
 

怎么了? 我想获取值bc,而无需手动移动和解析。 如何在函数内正确使用getopts

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

编辑#2:确定结果很好,我的外壳被弄乱了。 打开一个新窗口解决了它。 arg值的确在$ OPTARG中。

Magnus asked 2020-08-10T21:30:19Z
3个解决方案
88 votes

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

# local OPTIND:

#!/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

示例运行:

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

如果您注释掉# local OPTIND,则会得到以下结果:

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

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

Adrian Frühwirth answered 2020-08-10T21:30:43Z
10 votes

这是shell函数中getopts用法的简单示例:

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

输出:

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

正如@Adrian指出的那样,需要设置getopts(或OPTIND=1),因为Shell不会在多次调用getoptsman bash)之间自动重置OPTIND

getopts的基本语法为:

getopts OPTSTRING VARNAME [ARGS...]

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

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

  • OPTERR-要处理的下一个参数的索引,
  • OPTERR-将变量设置为getopts找到的选项的任何参数,
  • OPTERR(不是POSIX)-设置为0或1以指示Bash是否应显示getopts生成的错误消息。

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

kenorb answered 2020-08-10T21:31:42Z
5 votes

参数存储在变量$OPTARG中。

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

输出:

$ t -a bc
-a bc
a
bc
Ansgar Wiechers answered 2020-08-10T21:32:06Z
translate from https://stackoverflow.com:/questions/16654607/using-getopts-inside-a-bash-function