3

我知道如何在 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 中的建议?似乎正在重新排列论点。

4

2 回答 2

5

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

#!/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
于 2014-01-07T00:15:44.927 回答
1

如果您知道位置参数的数量,那么您可以执行以下操作:

#!/bin/bash

VAR=$1
shift
echo $VAR

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

例子:

> ./test.sh mist -a 2345 -p 45
mist
2345
于 2014-01-06T22:36:32.347 回答