【问题标题】:Command line argument validation library for BashBash 的命令行参数验证库
【发布时间】:2012-06-27 06:41:12
【问题描述】:

我正在寻找一个可重用的代码 sn-p,它为 bash 进行命令行参数验证。

理想情况下类似于 Apache Commons CLI 提供的功能:

Commons CLI 支持不同类型的选项:

  • 类似 POSIX 的选项(即 tar -zxvf foo.tar.gz)
  • 类似 GNU 的长选项(即 du --human-readable --max-depth=1)
  • 附加值的短选项(即 gcc -O2 foo.c)
  • 带有单个连字符的长选项(即 ant -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 脚本的开头包含这段代码 sn-p 并在脚本中重复使用它。

一定有这样的东西。我不相信我们都在编写达到这种效果或类似效果的代码:

#!/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

...

【问题讨论】:

  • 使用getopts 作为短选项。见BashFAQ/35。用 Python 编写脚本并使用 argparse
  • 我怀疑答案是缺少模块基础架构使得以可移植方式加载源库的工作量与每次重写选项解析的工作量大致相同。

标签: bash shell


【解决方案1】:

这是我使用的解决方案(在网上某个地方找到的,可能是这里本身,不记得了)。请注意,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" -- "$@")
# 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 shell 内置的替代实现(这只支持小选项):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2022-07-26
    • 1970-01-01
    相关资源
    最近更新 更多