在函数中调用的getopts没有拾取标志[重复]

问题描述 投票:3回答:2

这个问题在这里已有答案:

我有以下脚本,我从我的.bash_profile调用:

# Set directories based on current path
__set_dirs() {
    currdir=`pwd`
    if [[ ${currdir} =~ "\/path\/to\/main\/(.*)\/working\/([a-z]+)(/?.*)" ]]
    then
        ws=${BASH_REMATCH[1]}
        subdirs=${BASH_REMATCH[3]}
        stgdir=${ts}/${ws}/STAGING${subdirs}
    else
        echo "${currdir} is not a workspace"
        stgdir=""
    fi
}

# Update local version with staging version
upd() {
    __set_dirs
    if [[ -n ${stgdir} ]]
    then
        __overwrite=0
        while getopts "o" opt
        do
            case $opt in
                o)
                    __overwrite=1
                    ;;
                \?)
                    echo "Invalid option: -$OPTARG" >&2
                    ;;
            esac
        done

        echo "Updating ${currdir} with latest from ${stgdir}..."
        if [ ${__overwrite} -eq 0 ]
        then
            update -r ${stgdir} ${currdir}
        else
            echo "Overwriting all local changes!"
            update -r -w ${stgdir} ${currdir}
        fi
    fi
    unset __overwrite
}

当我执行

> upd -o

该标志被完全忽略 - 我从未看到消息“覆盖所有本地更改!”。我错过了某个地方吗?

更新:它确实有效,但只是我第一次运行脚本。从第二次开始,该标志被忽略。

bash getopts
2个回答
4
投票

好吧,想通了:

在穿过man page for getopts后,我发现了这个花絮(强调我的):

每次调用它时,getopts将要处理的下一个参数的索引放入变量OPTIND中。每次调用shell或shell脚本时,OPTIND都会初始化为1. shell不会自动重置OPTIND;如果要使用一组新参数,则必须在同一shell调用内多次调用getopts之间手动重置。

因为我只用.bashrc运行一次脚本,所以OPTIND只被初始化一次。我第一次运行这个功能,一切都是笨拙的。第二次,OPTIND设置为2,getopts没有找到任何东西,所以它继续前进。

有了这些知识,我修改了upd()OPTIND重置为1:

upd() {
    __set_dirs
    if [[ -n ${stgdir} ]]
    then
         __overwrite=0
         OPTIND=1
         while getopts "o" opt
...

修好了。 OPTIND:比你想象的更重要。


2
投票

getopts作用于传递给函数的参数,因此在您的情况下,您必须使用upd()调用"$@"函数,以将所有命令行参数传递到您的函数中。

例如:

test() {
  while getopts "o" opt; do
    case $opt in
    o)
      echo o
    ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
    ;;
    esac
  done
}
test # this wont work as $1, $2, ... are not set
test $@ # this will work as you pass along the command line parameters

编辑

我忽略了.bashrc部分,如果我上面的例子,我的运行shell,然后test -o按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.