使用 getopts 设置变量

使用 getopts 设置变量

我想使用 getopts 来解析 bash 函数的参数。

while getopts ${shortopts} arg; do

但在设置变量值时遇到问题。调用myfunc -v8myfunc -v 8设置vb为 的预期值8

myfunc -v 8
vb, arg:   ;  OPTARG: 8
vb: 8

但再次运行命令myfunc -v 21给出

myfunc -v 21
vb: 1

这是我处理选项的方法

myfunc
{
  local vb=1

  local arg
  local shortopts="Vuhv:"

  while getopts ${shortopts} arg; do
    case ${arg} in
      # ........................................................
      ("V")
        printf "%s\n" "V01 Jul 2021 Wk27"
        return
        ;;
      ("u")
        printf "%s\n" "-V, -u, -h"
        return
        ;;
      ("h")
        printf "%s\n" "Prints status returned by getopt."
        printf "%s\n" "-V  Displays version"
        printf "%s\n" "-u  Displays usage"
        printf "%s\n" "-h  Displays help."
        printf "%s\n" "-v, -vNUM  Sets verbosity level."

        printf "%s\n" "Example: getopt-status --"
        return
        ;;
      ("v")
        vb="$OPTARG" 
        printf '%s\n' "vb, arg: $arg  ;  OPTARG: $OPTARG"
        ;;
      :)
        echo "Current argument value, OPTARG: -$OPTARG" >&2
        echo "Must supply an argument to -$OPTARG" >&2
        ;;
      ?)
        printf "%s\n" "Invalid option, OPTARG: $OPTARG"
        ;;
    esac
  done

  echo "vb: $vb"

}

答案1

正如 ilkkachu 和其他人提到的,那里存在一些错误。return并将local在函数内工作,因为return将返回函数的退出代码。

这是一个可以给您一个想法的最小示例:

#!/usr/bin/env bash

die(){ echo >&2 "$@"; exit 1; }
usage(){ echo >&2 "usage: $0 [-u] [-v num] "; exit 0; }

shortopts=":Vuhv:"
while getopts "$shortopts" opt; do
        case $opt in
        u)      usage ;;
        v)      case $OPTARG in
                ''|*[!-0-9]*) die "invalid number $OPTARG" ;;
                *) val=$OPTARG ;;
                esac
                ;;
        :)      die "argument needed to -$OPTARG" ;;
        *)      die "invalid switch -$OPTARG" ;;
        esac
done
shift $((OPTIND - 1))

echo value="$val"

一些注意事项:

如果选项字符串的第一个字符是 :(冒号),这通常是无意义的,因为它前面没有选项字母,getopts 会切换到“静默错误报告模式”。在高效的脚本中,这通常是您想要的,因为它允许您自己处理错误,而不会被烦人的消息打扰。

更多请参见:https://wiki.bash-hackers.org/howto/getopts_tutorial

答案2

getopts在函数中使用时,您必须本地化OPTARG,尤其是OPTIND.

你可以做

myfunc() {
    local OPTIND OPTARG
    ...

并将getopts负责初始化它们。

相关内容