bash - 使用 getopts 读取一个可选参数并移动正确数量的参数

标签 bash

我正在编写一个简单的 bash 脚本,它采用一个可选参数 (-t),后跟一些附加参数。

我认为 getopts 是实现此目标的合理方法,但我很难获得所需的行为。我有以下内容:

foo() {
    baz=10
    while getopts ":t:" option; do
        case "$option" in
        t) baz=$OPTARG ;;
        esac
    done
    shift $((OPTIND - 1))
    bar -t $baz $1 $2 $3
}

问题是 $OPTIND 似乎不会根据参数是否存在而变化,所以我没有像预期的那样使用可选参数获得正确的行为(即,我可以'无论参数是否存在,都不会转移到正确数量的参数。

我希望以下两项都能正确执行:

foo a b c
foo -t 5 a b c

实现此目标的最简单方法是什么?我更喜欢不是 hack 的解决方案,因为我可能想使用额外的可选参数。

最佳答案

问题是您永远不会重置 $OPTIND,因此每次您调用 foo 时,它都会从最后一次处理的选项索引之后开始检查其参数。例如:

# $OPTIND is now 1
foo -t opt arg1 arg2 arg3
# the above recognizes -t opt as an option, and sets $OPTIND to 3

# $OPTIND is now 3
foo arg4 arg5 arg6
# the above recognizes that arg6 is not an option, so it leaves $OPTIND at 3

解决方案是在 foo 中本地化 $OPTIND,明确地将其设置为 1:

foo() {
    baz=10
    local OPTIND=1
    while getopts ":t:" option; do
        case "$option" in
        t) baz=$OPTARG ;;
        esac
    done
    shift $((OPTIND - 1))
    bar -t $baz $1 $2 $3
}

(您可能还想本地化 $baz,同时进行本地化。)

关于bash - 使用 getopts 读取一个可选参数并移动正确数量的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14656181/

相关文章:

linux - Makefile创建子目录并通过ID列表的文件下载一些文件

linux - 检查文件中的值是否大于或等于 bash 脚本中的值

windows - 如何将 .sh 文件与 Cygwin 相关联?

bash - 针对 bash 单维数组限制的更简洁的解决方法

linux - 阻止其他用户访问我的主目录中的特定目录?

linux - 如何使用sed命令更改limits.conf中的ulimit值?

linux - bash:递归地将父目录中的所有匹配文件移动到新的子目录

arrays - 如何在没有循环的情况下更改 bash 数组元素的值

bash - cp: 静音 "omitting directory"警告

bash - 使用 bash 提取文本文件中 2 个标记之间的行