4

我正在尝试在 bash 中使用 getopts 来解析命令行参数,但如果没有匹配的参数(或没有给出 cmdline 参数),我无法弄清楚如何实现“默认”操作。

这是迄今为止我尝试过的稍微简化的版本:

while getopts v:t:r:s:c: name;
do
        case $name in
        v) VALIDATE=1;;
        t) TEST=1;;
        r) REPORT=1;;
        s) SYNC=1;;
        c) CLEAR=1;;
        *) print_help; exit 2;;
        \?) print_help; exit 2;;
        esac
done

有没有(简单的)方法可以让它调用 print_help;2号出口;在不匹配的输入上?

4

4 回答 4

6

在您的问题和对 Aditya 回答的评论之间,我建议以下内容:

[getopts]$ cat go
#!/bin/bash

function print_help { echo "Usage" >&2 ; } 

while getopts vtrsc name; do
    case $name in
        v) VALIDATE=1;;
        t) TEST=1;;
        r) REPORT=1;;
        s) SYNC=1;;
        c) CLEAR=1;;
        ?) print_help; exit 2;;
    esac
done

echo "OPTIND: $OPTIND"
echo ${#@}

shift $((OPTIND - 1))

while (( "$#" )); do
    if [[ $1 == -* ]] ; then
        echo "All opts up front, please." >&2 ; print_help ; exit 2
    fi
    echo $1
    shift
done

由于每个都是布尔标志选项,因此您不需要(实际上也不需要)参数,因此我们去掉了冒号。这些字符都不在 IFS 中,因此我们不需要将其用引号括起来,无论如何这将是 getopts 的一个标记。

接下来,我们将 更改\?为单个?并去掉*,因为*会在文字之前匹配\?,我们不妨将规则组合成一个默认匹配。这是一件好事,因为任何带有-前缀的选项都应该是一个选项,如果他们指定了一个您不期望的选项,用户会认为程序会失败。

getopts将解析到不是参数的第一件事,并设置OPTIND为该位置的值。在这种情况下,我们将OPTIND - 1移出前面(因为 opts 是 0 索引的)。然后,我们将通过将它们移开、回显它们或如果它们以-.

并测试:

[getopts]$ ./go
OPTIND: 1
0
[getopts]$ ./go -t -v go go
OPTIND: 3
4
go
go
[getopts]$ ./go -d -v go go
./go: illegal option -- d
Usage
[getopts]$ ./go -t go -v go -d
OPTIND: 2
5
go
All opts up front, please.
Usage
于 2012-03-21T13:14:30.730 回答
4

尝试以下解决方法:

# Parse the arguments.
while getopts ':h?f:' opts; do
  case ${opts} in

    f) # Foo argument.
      ;;

    # My other arguments.

    \? | h | *) # Prints help.
      grep " .)\ #" $0
      exit 0
      ;;
  esac
done

所以基本上-?/-h会根据自己的来源打印带有注释的参数。指定:before 选项也将打印任何其他未知参数的帮助。

于 2015-12-03T23:32:52.843 回答
2

v:t:r:s:c: should be in double quotes

 "v:t:r:s:c:"

Based on the script you posted, maybe you don't require all those colons :

Also you don't need *)

于 2012-03-21T12:32:26.790 回答
1

如果要启用?以匹配无效选项,则需要在 getopts 选项字符串中提供前导冒号 -- :vtrsc。你也不需要在之前的反斜杠?

于 2012-03-21T13:37:22.870 回答