【问题标题】:Bash getopts: recognizing negative options (-x- or +x)?Bash getopts:识别否定选项(-x- 或 +x)?
【发布时间】:2017-03-06 10:05:51
【问题描述】:

(类似于this,但在 bash 中。)

我有一个现有的 bash 脚本,它使用内置的 getopts 来识别 -s(仅标志 - 无参数)。我发现我每次都使用该选项,所以我想将其设为默认值除非在命令行中指定了-s-+s。但是,尽管ksh getopts can handle +s,我在bash getopts manual 中找不到该功能。

我目前的解决方法是:

  1. 使用s: 这样我就可以通过$OPTARG="-" 识别-s-;或
  2. 用不同的选项替换-s,例如-d(表示“不要”)。

但是,如果我不小心指定了-s,#1 的问题是它会吞下下一个参数,而 #2 的问题是它使用了与我的肌肉记忆中已有的不同的开关字母。我希望有一种直接的方法可以在 bash 中解析 -s-+s

  • util-linux getopt(1) 似乎也没有+s。它可以处理可选参数,因此可以采用-s-。但是,我之前没有使用过getopt(1),因此希望能得到有关如何不射中自己的脚的建议。
  • BashFAQ 035 说“自己解析”。如果您已经编写了一个可以执行+s-s- 的例程,我很乐意看到它。

我当前的 arg 解析循环非常基础:

while getopts "nthps" opt ; do
    case "$opt" in
        <other cases cut>
        (s)     saw_s="yes"
                ;;
    esac
done
shift $((OPTIND-1))

【问题讨论】:

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


    【解决方案1】:

    负标志序列 (+abcdef +g) 与只有加号字符的正常序列 (-abcdef -g) 不同。因此,您可以简单地还原 + 前缀的标志值。

    负序的第二种形式同样简单。只需去掉最后一个字符 (-),然后否定正常的标志值。

    示例

    以下脚本接受所有提到的格式,例如-ns -n -s -n- -ns- +ns +n +s.

    arglist='ns'
    
    while (( $# )); do
      arg="$1"
    
      # Parse -abcdef- (negative form of -abcdef) options
      if [ "${arg:0:1}" = '-' -a "${arg#${arg%?}}" = '-' ]; then
        flag_val=no
        arg="${arg%?}" # -abcdef- becomes -abcdef
      elif [ "${arg:0:1}" = '+' ]; then
        flag_val=no
        arg="${arg/#+/-}"
      else
        flag_val=yes
      fi
    
      # OPTIND is the index of the next argument to be processed.
      # We are going to parse "$arg" from the beginning, so we need
      # to reset it to 1 before calling getopts.
      OPTIND=1
    
      while getopts "$arglist" opt "$arg"; do
        case "$opt" in
          s) saw_s="$flag_val" ;;
          n) saw_n="$flag_val" ;;
        esac
      done
    
      shift
    done
    
    # Set default values
    : ${saw_s:=yes}
    : ${saw_n:=no}
    
    printf "saw_s='%s'\nsaw_n='%s'\n" "$saw_s" "$saw_n"
    

    测试

    $ ./pargs.sh
    saw_s='yes'
    saw_n='no'
    $ ./pargs.sh -s
    saw_s='yes'
    saw_n='no'
    $ ./pargs.sh +s
    saw_s='no'
    saw_n='no'
    $ ./pargs.sh -s-
    saw_s='no'
    saw_n='no'
    $ ./pargs.sh -s- +s -s
    saw_s='yes'
    saw_n='no'
    $ ./pargs.sh -s +s
    saw_s='no'
    saw_n='no'
    $ ./pargs.sh +s -s
    saw_s='yes'
    saw_n='no'
    $ ./pargs.sh -s -s-
    saw_s='no'
    saw_n='no'
    $ ./pargs.sh -sn
    saw_s='yes'
    saw_n='yes'
    $ ./pargs.sh -sn -s-
    saw_s='no'
    saw_n='yes'
    $ ./pargs.sh -sn +s
    saw_s='no'
    saw_n='yes'
    $ ./pargs.sh +sn
    saw_s='no'
    saw_n='no'
    $ ./pargs.sh -sn-
    saw_s='no'
    saw_n='no'
    $ ./pargs.sh -sn- -n
    saw_s='no'
    saw_n='yes'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 2021-06-23
      • 2018-06-18
      相关资源
      最近更新 更多