需要有关 shell 脚本选项处理的帮助

需要有关 shell 脚本选项处理的帮助

我正在努力使脚本具有这种行为:

  • 我想传递这样的选项,./script -ab就像./script -a -b
  • 并具有以下逻辑:“a & b -> c”、“a & c -> c”、“b & c -> c”(单个选项正常运行)
  • 另外,我希望该脚本在没有任何选项的情况下调用脚本时回退到函数(例如帮助函数)

这是一些例子:

#!/usr/bin/env bash

if [[ ${#} -eq 0 ]]; then
    echo "Default function"
else
    while getopts ":a:b:c:" opt; do
        case ${opt} in
        a) echo "a" ;;
        b) echo "b" ;;
        c) echo "c" ;;
        *) echo -e "Invalid option: ${@}" ;;
        esac
    done
fi

任何帮助表示赞赏

答案1

最简单的方法可能是为每个选项设置标志,然后在循环之后检查 A 和 B 的标志是否都已设置,如果设置了则启用 C。

但是您可以将其建模为位图,其中 A 和 B 各占一位,而 C 是这两个位均已设置的状态。因此 A=01、B=10、C=11 加上两个位均被清除的默认状态。 (这些状态对应于十进制或十六进制的默认=0、A=1、B=2、C=3。)然后,当看到相应的选项时,只需设置适当的位即可。

就像这样:

#!/usr/bin/env bash

mode=0
while getopts "abc" opt; do
    case ${opt} in
        a) mode=$(( mode | 0x01 )) ;; # set rightmost bit
        b) mode=$(( mode | 0x02 )) ;; # set leftmost bit
        c) mode=$(( mode | 0x03 )) ;; # set both bits
        *) exit 1 ;;
    esac
done

echo "chosen mode is $mode (0 = default, 1 = a, 2 = b, 3 = c)"

请注意,您在文本中提到了-A和,但您的脚本有和。关心字母大小写,所以它们不一样。另外,冒号将选项标记为接受参数,但您似乎不需要它。-babgetoptsgetopts a:b:c:

答案2

(编辑以处理问题中的新请求)

你们非常接近。下面是我做过的事情。乍一看有点复杂,但它是一系列步骤设置默认值、解析命令行、检查错误的选项值或组合,然后编写主例程的脚本:

#!/usr/bin/env bash

# defaults for options
help=n
opt_a=1
opt_b=production
opt_c=0

# if no options from my user, print help message only
if [[ $# -lt 1 ]]; then help=y; fi

# parse command line
while getopts ':ha:b:c' OPTION; do
  case "${OPTION}" in
     h) help=y            ;;
     a) opt_a="${OPTARG}" ;;
     b) opt_b="${OPTARG}" ;;
     c) opt_c=1           ;;
    \?) echo "$0: Error: Invalid option: -${OPTARG}" >&2 ; exit 1 ;;
     :) echo "$0: Error: option -${OPTARG} requires an argument" >&2 ; exit 1 ;;
  esac
done
shift $((OPTIND - 1))

# request for help overrides other actions
if [[ ${help} == 'y' ]]; then
  # put code here to print a USAGE message
  exit 0
fi

# check and error out on bad options from my user
# check -b:
case "$opt_b" in
  production) ;;
     staging) ;;
          qa) ;;
           *) echo "$0: Error: unknown argument -b \"${opt_b}\", exiting" >&2 ; exit 1 ;;
esac

# script does its work starting from here

调用 with将按预期script-name -c -b qa解析选项-b和,并且也将起作用。-cscript-name -cb qa

我只给出了一个检查选项的例子(为了使答案简单);通常会有更多的代码来检查每个选项并响应合法和非法的选项组合。我通常将这些代码行塞入子例程中,这样它们就不会处于脚本主要工作流程的中间。

相关内容