如何解析shell中的长格式参数?

时间:2012-02-14 03:39:10

标签: bash shell sh

我看到的所有内容都使用getopt或稍微有点getopts的{​​{1}},它只支持单字符选项(例如-h但不支持--help)。我想做很长的选择。

3 个答案:

答案 0 :(得分:14)

我做过类似this的事情:

_setArgs(){
  while [ "${1:-}" != "" ]; do
    case "$1" in
      "-c" | "--configFile")
        shift
        configFile=$1
        ;;
      "-f" | "--forceUpdate")
        forceUpdate=true
        ;;
      "-r" | "--forceRetry")
        forceRetry=true
        ;;
    esac
    shift
  done
}

正如您所看到的,这可以很好地支持单字符和更长的选项。它允许将值与每个参数相关联,如--configFile的情况。它也是相当可扩展的,没有人为限制,可以配置哪些选项等。

如上所述,{b}“严格”模式("${1:-}")运行时,set -euo pipefail可防止出现“未绑定变量”错误。

答案 1 :(得分:7)

假设您“想要做出花哨的长选项”,无论使用哪种工具,只需使用getoptgetopts似乎主要用于便携性至关重要)。这是关于您将获得的最大复杂性的example

params="$(getopt -o e:hv -l exclude:,help,verbose --name "$(basename "$0")" -- "$@")"

if [ $? -ne 0 ]
then
    usage
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -e|--exclude)
            excludes+=("$2")
            shift 2
            ;;
        -h|--help)
            usage
            ;;
        -v|--verbose)
            verbose='--verbose'
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done

使用此代码,您可以多次指定-e / --exclude${excludes[@]}将包含所有给定的排除。处理完毕后(--始终存在)剩余的任何内容都存储在$@

答案 2 :(得分:0)

我创建了一个bash函数,该函数最易于使用并且不需要自定义。只需使用该函数并传递所有带有或不带有参数的长选项,该函数就会将它们设置为变量,并在脚本中将相应的选项参数作为值。

function get_longOpt {
  ## Pass all the script's long options to this function.
  ## It will parse all long options with its arguments,
  ## will convert the option name to a variable and
  ## convert its option value to the variable's value.
  ## If the option does not have an argument, the
  ## resulting variable's value will be set to true.
  ## Works properly when providing long options, only.
  ## Arguments to options may not start with two dashes.
  ##
  ####  Usage
  ##
  ## get_longOpt $@
  ##
  ##  May expand to:
  ##
  ## get_longOpt --myOption optimopti --longNumber 1000 --enableMe --hexNumber 0x16
  ##
  ### Results in the bash interpretation of:
  ## myOption=optimopti
  ## longNumber=1000
  ## enableMe=true
  ## hexNumber=0x16
  ##
  local -a opt_list=( $@ )
  local -A opt_map
  local -i index=0
  local next_item
  for item in ${opt_list[@]}; do
    # Convert arg list to map.
    let index++
    next_item="${opt_list[$index]}"
    if   [[ "${item}" == --* ]] \
      && [[ "${next_item}" != --* ]] \
      && [[ ! -z "${next_item}" ]]
    then
      item="$(printf '%s' "${item##*-}")"
      opt_map[${item}]="${next_item}"
    elif [[ "${item}" == --* ]] \
      && { [[ "${next_item}" == --* ]] \
      || [[ -z "${next_item}" ]]; }
    then
      item="$(printf '%s' "${item##*-}")"
      opt_map[${item}]=true
    fi
  done
  for item in ${!opt_map[@]}; do
    # Convert map keys to shell vars.
    value="${opt_map[$item]}"
    [[ ! -z "${value}" ]] && \
    printf -v "$item" '%s' "$value"
  done
}

可在此处获取最新的原始源代码:

https://github.com/theAkito/akito-libbash/blob/master/bishy.bash