没有 cmd 时 getopts 打印帮助。行参数匹配

pru*_*nat 4 bash shell getopt getopts command-line-arguments

我试图在 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
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*her 5

在您的问题和对 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
Run Code Online (Sandbox Code Playgroud)

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

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

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
Run Code Online (Sandbox Code Playgroud)