【问题标题】:getopts printing help when no cmd. line argument was matchedgetopts 在没有命令时打印帮助。行参数匹配
【发布时间】:2012-04-05 23:09:28
【问题描述】:

我正在尝试在 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号出口;输入不匹配?

【问题讨论】:

    标签: bash shell command-line-arguments getopt getopts


    【解决方案1】:

    在您的问题和 Aditya 回答的 cmets 之间寻找,我建议如下:

    [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
    

    【讨论】:

      【解决方案2】:

      尝试以下解决方法:

      # 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 会根据自己的来源使用 cmets 打印参数。在选项之前指定: 也会打印任何其他未知参数的帮助。

      【讨论】:

      • 很好地利用了 grep。节省编写打印帮助函数的时间。我确实需要添加“h\?”到 arg 列表以避免 illegal option 输出。
      【解决方案3】:

      v:t:r:s:c: 应该用双引号引起来

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

      根据您发布的脚本,也许您不需要所有这些冒号:

      你也不需要*)

      【讨论】:

      • 谢谢,有什么方法可以匹配“非参数”,例如“./script asdf”?
      • 我不知道我的头顶。你用更新的脚本试过了吗?
      • 当 getopts 返回时,OPTIND 设置为第一个非选项参数的索引。
      • 该字符串不需要被引用,因为它不包含空格。
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2011-11-18
        • 1970-01-01
        • 2011-07-03
        • 2018-05-15
        • 1970-01-01
        • 1970-01-01
        • 2017-05-31
        • 1970-01-01
        • 2018-04-18
        相关资源
        最近更新 更多