Bash getopts : recognizing negative options (-x- or +x)?

标签 bash shell command-line-arguments getopt getopts

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

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

我目前的解决方法是:

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

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

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

我当前的 arg-parsing 循环非常基础:

while getopts "nthps" opt ; do
    case "$opt" in
        <other cases cut>
        (s)     saw_s="yes"
                ;;
    esac
done
shift $((OPTIND-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'

关于Bash getopts : recognizing negative options (-x- or +x)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40221636/

相关文章:

bash - TCL/Expect 相当于 Bash $@ 或如何将参数传递给 TCL/Expect 中的衍生进程

java - 从运行的应用程序中恢复Jar

java - 当我在java中运行sshpass命令时找不到它

linux - 如何检查 bash 脚本目录中是否存在与正则表达式匹配的文件?

linux - 如何使用脚本获取正在运行的 shell 的名称?

shell - 如何在 unix 中使用 awk 列出数组值并对其进行编号

r - R 中有处理命令行选项的包吗?

shell - 使用运算符 j 操作 zsh 数组

linux - crontab 执行 shell 脚本 : Mount error(13): Permission denied

Java执行-o选项