How can I parse long-form arguments in shell?

此生再无相见时 提交于 2019-12-03 12:32:04

I've done something like this:

_setArgs(){
  while [ "${1:-}" != "" ]; do
    case "$1" in
      "-c" | "--configFile")
        shift
        configFile=$1
        ;;
      "-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.

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

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

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

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!