【问题标题】:new to Bash - keep getting Illegal option errorBash 新手 - 不断收到非法选项错误
【发布时间】:2014-05-19 12:13:18
【问题描述】:

我对 ubuntu 和 bash 脚本非常陌生,想知道为什么我在使用 GETOPTS 时可能会收到此错误。

这是我用来运行它的代码。

sh /home/ubuntu/Desktop/test.sh -f /home/u/Desktop/ -p 'TEST'

我认为我正确调用了脚本,它应该使用 grap 搜索我作为搜索词输入的词。但由于某种原因它没有。任何关于我在使用 grep 时作为一般规则可以做什么的建议也将不胜感激,谢谢。

#!/bin/bash

valid=0
file_arg=""
display_help=""
column=""
pattern=""

while getopts f:d:s:m: opt
do
    case "$opt" in
        d)  display_help=$OPTARG
            ;;
        f)  file_arg=$OPTARG
            ;;
        c)  column=$OPTARG
            ;;
        p)  pattern=$OPTARG
            ;;
        *)  valid=1
            break
            ;;
    esac
done

if [ $valid -eq "0" ]
then
    if [ $pattern != "" ]
    then
        cat $file_arg | grep $pattern
    else
        cat $file
    fi
else
    echo -n "Usage: FILE -f <name> | COLUMN -> -c <name> | HELP -> -d | PATTERN -> -p <expression>"
fi

【问题讨论】:

    标签: bash shell ubuntu-13.04


    【解决方案1】:

    getopts 中,您没有指定p 选项,您只有f:d:s:m: 选项。

    我认为您的意思是 p 而不是 m,反之亦然。

    应该是f:d:s:m:p:f:d:s:p:

    【讨论】:

      【解决方案2】:

      正如 Jayesh 所提到的,您的脚本还有一些其他问题,您需要包含 getopt 的所有参数,但您还需要小心字符串比较,这里有几个修复建议:

      (有关字符串比较信息,请参阅http://www.tldp.org/LDP/abs/html/comparison-ops.html

      #!/bin/bash
      
      # switch around valid, convention is 1 == true and 0 == false
      valid=1
      file_arg=""
      display_help=""
      column=""
      pattern=""
      
      # getopt patterns need to match following case statement
      while getopts f:d:c:p: opt;
      do
          case $opt in
              d)  display_help=$OPTARG
                  ;;
              f)  file_arg=$OPTARG
                  ;;
              c)  column=$OPTARG
                  ;;
              p)  pattern=$OPTARG
                  ;;
              *)  valid=0
                  break
                  ;;
          esac
      done
      
      # changed value to reflect true false convention
      if [ "$valid" -eq "1" ]
      then
          # string comparison in bash should be done using specific operators
          if [ -n "$pattern" ]
          then
              cat $file_arg | grep $pattern
          else
              # typo, this should be file_arg?
              cat $file_arg
          fi
      else
          echo -n "Usage: FILE -f <name> | COLUMN -> -c <name> | HELP -> -d | PATTERN -> -p <expression>"
      fi
      

      【讨论】:

        【解决方案3】:

        您还应该考虑getopts 的错误抑制和错误处理功能。

        如果选项字符串的第一个字符是冒号 (:),那么getopts 将不会报告错误,而是会提供一种自行处理错误的方法。然后可以在您的案例条件处理中使用两个额外的字符:

        • ? 如果输入了无效选项,则$opt 将设置为?$OPTARG 将保留无效字符,例如如果使用了-z(不在您的选项字符串中),则$OPTARG 将设置为z

        • : 如果用户省略了所需的附加参数,则$opt 将设置为:$OPTARG 将保存命令字符,例如如果使用-p 而不是-p arg,则$OPTARG 将设置为p

        如果实现了这一点,那么 * 的全部内容将变得多余,应该被删除。注意:如果你把它留在里面并且它高于?: 那么你会问问题。还要确保 ?\?) 这样转义。

        希望这会有所帮助。

        # Note the addition of the inital colon before 'f'.
        while getopts :f:d:c:p: opt;
        do
            case $opt in
                d)  display_help=$OPTARG
                    ;;
                f)  file_arg=$OPTARG
                    ;;
                c)  column=$OPTARG
                    ;;
                p)  pattern=$OPTARG
                    ;;
        
                # Option error handling.
        
                \?) valid=0
                    echo "An invalid option has been entered: $OPTARG"
                    ;;
        
                :)  valid=0
                    echo "The additional argument for option $OPTARG was omitted."
                    ;;
        
                # This is now redundant:
                # *)  valid=0
                #     break
                #     ;;
            esac
        done
        

        【讨论】:

        • 如果? 没有被转义,那么它匹配任何东西并且你永远不会遇到: 的情况,所以缺少的参数被报告为无效选项。
        • 感谢您的澄清标记。有用的知识。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-14
        • 1970-01-01
        • 2022-07-21
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 2020-11-29
        相关资源
        最近更新 更多