bash - 如何在 Bash 中使用 getopts 允许非可选参数位于可选参数之前?

标签 bash getopts

我知道如何在 Bash 中使用 getopts 处理可选参数

#!/bin/bash

while getopts ":a:p:drh" opt; do
  case "$opt" in
    a) echo $OPTARG;;
  esac
done

但是如果我的脚本需要 ./script.sh arg1 [options],我该如何告诉 getopts 跳过 arg1?

$ ./script.sh -a 1234
1234
$ ./script.sh arg1 -a 1234
$ ./script.sh arg1
$ ./script.sh -a 1234 arg1
1234

如我所见,如果参数放在最后一个位置,我可以处理该参数。在 getopts 中我需要什么“正则表达式”来允许我的位置参数位于可选参数的前面?

来自How to allow non-option arguments in any order to getopt?的建议似乎在重新排列参数。

最佳答案

这是我的做法。您可以在任何地方放置许多非可选参数。

#!/bin/bash

while [ $# -gt 0]; do
  while getopts ":a:p:drh" opt; do
    case "$opt" in
      a) echo $OPTARG; shift;;
      p) echo $OPTARG; shift;;
      d) echo Option d;;
      r) echo Option r;;
      h) echo Option h;;
      \?) echo unknown Option;;
      :) echo missing required parameter for Option $OPT;;
    esac
    shift
    OPTIND=1
  done
  if [ $# -gt 0 ]; then
    POSITIONALPARAM=(${POSITIONALPARAM[@]} $1)
    shift
    OPTIND=1
  fi
done

echo ${POSITIONALPARAM[@]}

内层循环解析参数。每当遇到非选项参数时,就会退出内循环。外部循环将获取下一个非选项参数。内部循环将在非选项参数被删除后恢复读取下一个可选参数,依此类推。

作为Chrono Kitsune建议我解释一下,移位会删除第一个参数(可选或不可选)并将所有内容向左移动一个位置。 $1 被移除,$2 变为 $1$3 变为 $2 等等向前。这使脚本可以控制移动非可选参数,直到它变为 $1

shift 和重置 OPTIND 都使这成为可能。感谢Chrono Kitsune对于将 OPTIND 重置为 1 而不是 0 的建议。

./sample.bash -a one -p two more -d sample

输出:

one
two
Option d
more sample

现在让我们用不同位置的参数调用脚本。

./sample.bash more -a one -p two -d sample

输出:

one
two
Option d
more sample

关于bash - 如何在 Bash 中使用 getopts 允许非可选参数位于可选参数之前?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20960235/

相关文章:

bash - 如何在现有 txt 文件中用 Bash 编写第二列

bash - 从具有二进制模式字符串的文件中删除行

linux - 需要将 getopts 与一个参数或另一个参数一起使用

linux - BASH getopts 具有相同选项的多个脚本

c - poptGetArgs 返回 null。

python - Linux - 如何将位于多个子目录中的相同扩展名的文件直接复制到一个文件中?

linux - Bash - 格式化值

linux - 如何在不生成临时文件的情况下在 shell 脚本中在生成的文件前面附加行数

linux - RHEL6 getopts 似乎没有工作

bash - 提供管道 bash 脚本的选项