getopts OPTIND 的工作原理

getopts OPTIND 的工作原理

我想了解如何OPTIND工作getopts。如果我想跳过前几个位置参数,我应该如何设置OPTIND

而且因为 OPTIND 不会自动重置,所以我需要知道如何在多次调用 getopts 之间准确地手动重置。

因为在第一次调用时我收到报告的错误

gopi -z
/usr/local/bin/bash: option requires an argument -- z

但是第二次调用,没有报错

gopi -z

这是函数

 gopi ()
 {

  local parg=""
  while (( $# > 0 )); do
    parg="$1"
    case $parg in
     ("-s"|"--silent") opstring=":n:z:" ;;
     (*) break ;;
    esac  # case ends here
    shift 1
  done
 
  while getopts "$opstring" opname; do
   case ${opname} in
     ("n") dothis ;;
     ("z") dothat ;;
     (?)
       ## Invalid Option Found
       echo "Invalid option: -$OPTARG" 1>&2
       exit 1
       ;;
     (:)
       ## Required option argument not found
       echo "Option -$OPTARG requires an argument" 1>&2
       exit 1
       ;;
   esac
  done
 }

答案1

而且因为 OPTIND 不会自动重置,所以我需要知道如何在多次调用 getopts 之间准确地手动重置。

Bash 的手册页显示(在getopts描述下):

OPTIND每次调用 shell 或 shell 脚本时都会初始化为 1。

这暗示将其重置为1应该可以工作。POSIX 描述中对此有更清楚的说明getopts:

如果应用程序设置OPTIND对于值 1,可以使用一组新参数:当前位置参数或新的 arg 值。在单个 shell 执行环境中多次调用 getopts 的任何其他尝试,其参数(位置参数或 arg 操作数)在所有调用中都不相同,或者使用OPTIND将值修改为 1 以外的值会产生未指定的结果。

在这里,第二次调用foo错过了第一个参数-a,但最后一次调用foo再次看到了两个参数:

foo() {
    echo --
    while getopts abc opt; do
        echo $opt
    done
}
foo -abc
foo -a -b
OPTIND=1
foo -a -b

OPTIND=1当然,在调用之前在函数开头设置更有意义getopts


请注意,研究 的值并没有多大用处OPTIND。这不是完整的事实,因为它不包含有关单个命令行参数内的位置的信息。例如,使用上面-abc第一次调用中的参数,在循环内取值 1, 1, 2,当前字符位置不可见。 (在 Bash 和 ksh 中,Zsh 似乎在输入函数时重置,而 yash 对值中参数内的位置进行编码。)fooOPTINDOPTINDOPTIND

相关内容