在使用getopts时,如何在bash函数中共享解析代码的选项?

时间:2013-08-13 04:13:33

标签: bash shell dry getopts

如何在Bash函数中清理此选项解析代码?它被复制粘贴到许多功能中,这些功能需要一个简单的“-h”标志来打印使用。我宁愿使用逻辑等效于

的通用例程
local prefix_opt1
local prefix_opt2
....
__handle_opts "usage message" "additional getopts flags" "prefix"

例如:

local foo_k
local foo_v
__handle_opts "Usage: ${FUNCNAME[0]}" [-k key -v version] widget\nBuild a widget using the key and version." "k:v:" "foo_"

if [[ -z $foo_k ]] ; then
    foo_k="default value"
fi
.....

这些函数将在一个dot-bashrc文件中“源”。

以下是代码的样子(注意:某些函数确实通过标志获取选项):

function kitten_pet {

  local usage="Usage: ${FUNCNAME[0]} [-h] <kitten>\nPet the kitten."

  ################################################
  local help=0
  local error=0
  local OPTIND
  local opt
  while getopts ":h" opt "$@"
  do
    case $opt in

      h)
        echo -e "$usage"
        help=1
        break
        ;;

      \?)
        echo "Invalid option: -$OPTARG"
        error=1
        break
        ;;
    esac
  done
  if [ $error -gt 0 ] || [ $help -gt 0 ] ; then
    return 1
  fi
  shift $((OPTIND-1))
  ################################################

  if [ $# -lt 1 ]
  then
    echo -e "$usage"
    return 1
  fi

  __kitten_pet "$1"
}

通常我会使用node-commander或node-optimist之类的东西,然后用JavaScript(或者Python)编写脚本以满足脚本需求,但这次我试图让Bash工作。但巴什正在抨击我。

1 个答案:

答案 0 :(得分:0)

将通用选项解析器传递给调用脚本将要管理的选项列表。

对于要在调用脚本中管理的每个选项,请创建一个名为option_X_parser的函数。这些选项解析器函数应接受可选参数($ OPTARG),并应返回0(成功)或1(错误)。

泛型选项解析器应使用其通用选项(例如,“h”,“n”和“v”)以及调用程序提供的选项来构建shell case语句。对于那些具有关联选项解析器函数的选项,case语句应该包括选项解析器的调用。

每个已配置选项应该有一个case语句,如果已定义,则应调用用户提供的函数,或者通过设置全局变量(.eg,opt_X来一般管理,其中X是具体选项)。

例如:

__handle_options "$usage", 'hni:v'

option_h_parser() { echo "$usage"; exit 1 ; } option_n_parser() { norun=1 ; return 0 ; } option_v_parser() { verbose=1 ; return 0 ; } option_i_parser() { insert_at="$1" ; return 0 ; } # invoke with argument

基本上,根据选项字母使用隐含的函数名称。

通用选项处理函数检查每个选项解析器的返回值。像这样的东西:

function_name="option_${opt}_parser"
if eval "$function_name $OPTARG" ; then
  # option is good
else
  error "'$opt' parser failed."
  exit 2
fi