使用 getopt 具有可选值的选项

使用 getopt 具有可选值的选项

我有以下功能,并想了解如何使用 来设置具有可选值的选项getopt

希望-w采用默认值

region -w -- "Text"

-w 1需要可选的数值。

region -w 1 -- "Text"

函数在这里

region ()
{
  # Process command line options
  shortopts="hw::"
  longopts="help,version,warning:"

  opts=$(getopt -o "$shortopts" -l "$longopts"  \
            -n "$(basename $0)" -- "$@")
  if [ $? -eq 0 ]; then
    eval "set -- ${opts}"
    while [ $# -gt 0 ]; do
      case "$1" in
      -h|-\?|--help)
        printf "%s\n" "Todo."
        shift
        break
        ;;
      -w|--warning)
        case "$2" in
          "1") local -r warn="first";  shift 2  ;;
            *) local -r warn="all";    shift 2  ;;
         esac
         local -r f=1
         ;;
      --)
         local -r f=1
         shift
         break
         ;;
      esac
    done
  else
    shorthelp=1 # getopt returned (and reported) an error.
  fi
    
}

答案1

您可能不会喜欢这个答案:为了向可选地采用参数的选项提供参数,您不允许使用空格:

$ getopt -o 'w::' -- -w -- arg
 -w '' -- 'arg'

$ getopt -o 'w::' -- -w 1 -- arg
 -w '' -- '1' 'arg'

$ getopt -o 'w::' -- -w1 -- arg
 -w '1' -- 'arg'

同样,对于选项长参数,您必须使用=

$ getopt -o '' -l 'warning::' -- --warning -- arg
 --warning '' -- 'arg'

$ getopt -o '' -l 'warning::' -- --warning 1 -- arg
 --warning '' -- '1' 'arg'

$ getopt -o '' -l 'warning::' -- --warning=1 -- arg
 --warning '1' -- 'arg'

从手册页:

一个简单的短选项是一个“-”后跟一个短选项字符[...]如果该选项有一个可选参数,必须直接写在选项字符之后如果存在的话。

长选项通常以 '--' 开头 [...] 如果选项有可选参数,它必须直接写在长选项名称之后,并用“=”分隔,如果存在(如果添加“=”但其后面没有任何内容,则会被解释为好像没有参数存在;这是一个小错误,请参阅错误)。


只是关于代码布局的代​​码审查评论:在 if-else-fi 构造中,将短分支放在第一位。在这里,当我到达 时else,我必须进行扫描以记住if情况是什么。

这还允许您以“断言”风格编写并减少函数的“主”代码:

region ()
{
  # Process command line options
  shortopts="hw::"
  longopts="help,version,warning:"

  opts=$(getopt -o "$shortopts" -l "$longopts"  \
            -n "$(basename $0)" -- "$@")
  if [ $? -ne 0 ]; then
    shorthelp=1 # getopt returned (and reported) an error.
    return
  fi

  eval "set -- $opts"
  # ...

另外,您可以直接检查退出状态并仍然分配给变量(我还在此处删除了基本名称调用)

  if ! opts=$(getopt -o "$shortopts" -l "$longopts" -n "${0##*/}" -- "$@")
  then
    shorthelp=1 # getopt returned (and reported) an error.
    return
  fi

使用 -w 我设置 level=1。否则,对于 -wNUM 我设置 level=NUM

  local level=0
  #...
      case "$1" in
      -w|--warning)
         level=${2:-"1"}
         ;;

即采用${var:-default}参数扩展的形式。

相关内容