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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9271381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:33:47  来源:igfitidea点击:

How can I parse long-form arguments in shell?

bashshellsh

提问by Ian Bicking

Everything I see uses getoptor the slightly-fancier getoptswhich only supports one-character options (e.g., -hbut not --help). I want to do fancy long options.

我看到的所有东西都使用getopt或稍微getopts支持一个字符的选项(例如,-h但不支持--help)。我想做一些花哨的长选项。

回答by ziesemer

I've done something like this:

我已经做了一些类似这样

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

As you can see, this supports both the single-character and the longer options nicely. It allows for values to be associated with each argument, as in the case of --configFile. It's also quite extensible, with no artificial limitations as to what options can be configured, etc.

如您所见,这很好地支持单字符和更长的选项。它允许将值与每个参数相关联,如--configFile. 它也具有很强的可扩展性,对可以配置的选项等没有人为限制。

As included above, the "${1:-}"prevents an "unbound variable" error when running in bash "strict" mode (set -euo pipefail).

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

回答by l0b0

Assuming that you "want to do fancy long options" regardless of the tool, just go with getopt(getoptsseems to be mainly used when portability is crucial). Here's an exampleof about the maximum complexity that you'll get:

假设您“想要做花哨的长选项”而不管工具如何,只需使用getopt(getopts似乎主要在可移植性至关重要时使用)。以下是您将获得的最大复杂度的示例

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

if [ $? -ne 0 ]
then
    usage
fi

eval set -- "$params"
unset params

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

With this code, you can specify -e/--excludemore than once, and ${excludes[@]}will contain all of the given excludes. After processing (--is always present) anything remaining is stored in $@.

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