2012-06-27 85 views
3

我正在寻找一个可重用的代码片断,它为bash执行命令行参数验证。Bash的命令行参数验证库

理想一些类似于由Apache的百科全书CLI提供的功能:

共享CLI支持不同类型的选择:

  • POSIX类似的选项
  • (即焦油-zxvf的foo.tar.gz。)
  • GNU等长选项(即杜--human可读--max深度= 1)
  • 短选项附值(即GCC -O2 foo.c的)
  • 长选项与单个连字符(即。蚂蚁-projecthelp)
  • ...

,并自动生成程序中的“用法”的消息,像这样:

usage: ls 
-A,--almost-all   do not list implied . and .. 
-a,--all     do not hide entries starting with . 
-B,--ignore-backups  do not list implied entried ending with ~ 
-b,--escape    print octal escapes for nongraphic characters 
    --block-size <SIZE> use SIZE-byte blocks 
-c      with -lt: sort by, and show, ctime (time of last 
          modification of file status information) with 
          -l:show ctime and sort by name otherwise: sort 
          by ctime 
-C      list entries by columns 

我将包括之初此代码段我Bash脚本并跨脚本重用它。

一定有这样的事情。我不相信我们都编写代码来这种效果或类似:

#!/bin/bash 

NUMBER_OF_REQUIRED_COMMAND_LINE_ARGUMENTS=3 

number_of_supplied_command_line_arguments=$# 

function show_command_usage() { 
    echo usage: 
    (...) 
} 

if ((number_of_supplied_command_line_arguments < NUMBER_OF_REQUIRED_COMMAND_LINE_ARGUMENTS)); then 
    show_command_usage 
    exit 
fi 

... 
+3

使用'getopts'作为简短选项。参见[BashFAQ/35](http://mywiki.wooledge.org/BashFAQ/035)。用Python编写脚本并使用[argparse](http://docs.python.org/library/argparse.html)。 –

+0

我怀疑答案是缺乏模块基础结构使得以可移植的方式加载源库与每次重写选项解析大致相同的工作量。 – tripleee

回答

5

这是我使用的解决方案(发现它在网络上的某个地方,也许在这里本身,不记得是肯定的)。请注意,GNU getopt(/usr/bin/getopt)确实支持使用选项-a的单短划线长选项(ant -projecthelp样式),但是我没有使用它,因此它在示例中未显示。

此代码解析为3个选项:--host value-h value--port value-p value--table value-t value。在情况下所需的参数没有被设置,因为它的测试是

# Get and parse options using /usr/bin/getopt 
OPTIONS=$(getopt -o h:p:t: --long host:,port:,table: -n "$0" -- "[email protected]") 
# Note the quotes around `$OPTIONS': they are essential for handling spaces in 
# option values! 
eval set -- "$OPTIONS" 

while true ; do 
    case "$1" in 
      -h|--host) HOST=$2 ; shift 2 ;; 
      -t|--table)TABLE=$2 ; shift 2 ;; 
      -p|--port) 
        case "$2" in 
          "") PORT=1313; shift 2 ;; 
          *) PORT=$2; shift 2 ;; 
        esac;; 
      --) shift ; break ;; 
      *) echo "Internal error!" ; exit 1 ;; 
    esac 
done 
if [[ -z "$HOST" ]] || [[-z "$TABLE" ]] || [[ -z "$PORT" ]] ; then 
    usage() 
    exit 
if 

使用getopts壳内建的替代实现(这只支持小选项):

while getopts ":h:p:t:" option; do 
    case "$option" in 
     h) HOST=$OPTARG ;; 
     p) PORT=$OPTARG ;; 
     t) TABLE=$OPTARG ;; 
     *) usage(); exit 1 ;; 
    esac 
done 
if [[ -z "$HOST" ]] || [[-z "$TABLE" ]] || [[ -z "$PORT" ]] ; then 
    usage() 
    exit 
if 

shift $((OPTIND - 1)) 

进一步阅读为GNU getoptgetopts bash builtin