美文网首页Shell 脚本成长笔记
选项处理(三)使用 getopt 处理多命令行选项

选项处理(三)使用 getopt 处理多命令行选项

作者: 赵者也 | 来源:发表于2017-05-05 20:35 被阅读735次

    getopt 命令与 getopts 的功能很相似,也是用于解析命令行的选项和参数,使其可以被 Shell 程序简单地解析。不同的是,getopt 命令是 Linux 下的命令行工具,并且 getopt 支持命令行的长选项(比如,--some-option)。另外,在脚本中它们的调用方式也不同。

    getopt 的语法类似如下:

    getopt [options] [--] optstring parameters
    getopt [options] -o|--options optstring [options] [--] parameters
    

    下面是一个示例:

    $ getopt f:vl -vl -f/local/filename.conf param_1
    -v -l -f /local/filename.conf -- param_1
    

    上例中,“f:vl” 对应 getopt 命令语法中的 optstring(选项字符串),“-vl -f/local/filename.conf param_1” 对应 getopt 命令语法中的 parameters(getopt 命令的参数)。因此,getopt 会按照 optstring 的设置,将 parameters 解析为相应的选项和参数。

    所以,“-vl” 被解析为了 “-v” 和 “-l”。与 getopts 类似,因为在选项字符串中 “f” 后有一个冒号(:),所以 “-f/local/filename.conf” 被解析为 “-f /local/filename.conf”。然后解析后的命令行选项和参数之间使用双连字符(--)分隔。

    那么我们在 Shell 脚本中怎样使用 getopt 命令来重写我们的命令行参数呢?

    实例1
    #! /bin/bash
    
    # 将 getopt 解析后的内容设置到位置参数
    set -- `getopt f:vl "$@"`
    
    while [ $# -gt 0 ]
    do
            echo $1
            shift
    done
    

    此脚本的运行效果如下:

    显示效果

    此脚本中的 set 命令语句中,“getopt f:vl "$@"” 表示将传递给脚本的命令行选项和参数作为 getopt 命令的参数,由 getopt 命令解析处理。整个 set 命令语句 “set -- getopt f:vl "$@"” 则表示将 getopt 命令的输出作为值依次(从左至右)赋值给位置参数(“set -- [args]” 命令会把指定的参数 [args] 依次赋值给位置参数)。

    实例2
    #! /bin/bash
    
    vflag=off
    output=""
    filename=""
    
    set -- `getopt hvf:o: "$@"`
    
    function usage() {
            echo "USAGE:"
            echo "  myscript [-h] [-v] [-f <filename>] [-o <filename>]"
            exit -1
    }
    
    while [ $# -gt 0 ]
    do
            case "$1" in
                    -v)
                            vflag=on
                            ;;
                    -f)
                            filename=$2
                            if [ ! -f $filename ]
                            then
                                    echo "The source file $filename doesn't exist!"
                                    exit
                            else
                                    shift
                            fi
                            ;;
                    -o)
                            output=$2
                            if [ ! -d `dirname $output` ]
                            then
                                    echo "The output path `dirname $output` doesn't exist!"
                                    exit
                            else
                                    shift
                            fi
                            ;;
                    -h)
                            usage
                            exit
                            ;;
                    --)
                            shift
                            break
                            ;;
                    -*)
                            echo "Invalid option: $1"
                            usage
                            exit 2
                            ;;
                    *)
                            break
                            ;;
            esac
            shift
    done
    

    此脚本的运行效果如下:

    显示效果
    实例3

    我们在前面提到 getopt 还有一个功能是支持长选项(--long-options),下面是一个使用 getopt 处理长选项的实例:

    #! /bin/bash
    
    vflag=off
    output=""
    filename=""
    
    set -- `getopt hvf:o: "$@"`
    
    function usage() {
            echo "USAGE:"
            echo "  myscript [-h] [-v] [-f <filename>] [-o <filename>]"
            exit -1
    }
    
    while [ $# -gt 0 ]
    do
            case "$1" in
                    -v)
                            vflag=on
                            ;;
                    -f)
                            filename=$2
                            if [ ! -f $filename ]
                            then
                                    echo "The source file $filename doesn't exist!"
                                    exit
                else
                    shift
                fi
                            ;;
                    -o)
                            output=$2
                            if [ ! -d `dirname $output` ]
                            then
                                    echo "The output path `dirname $output` doesn't exist!"
                                    exit
                else
                    shift
                fi
                            ;;
                    -h)
                            usage
                            exit
                            ;;
                    --)
                shift
                break
                ;;
            -*)
                            echo "Invalid option: $1"
                usage
                            exit 2
                            ;;
                    *)
                break
                            ;;
            esac
        shift
    done
    

    上述脚本中的 “getopt -o a::bc: --long arga::,argb,argc: -n 'getopt_longopt.sh' -- "$@"” 一行脚本中,getopt 命令的 “-o” 选项表示告诉 getopt 识别哪些短(一个字符)的选项。getopt 命令的 “--long” (或 -l) 选项表示告诉 getopt 识别哪些长选项。getopt 命令的 “-n” 选项告诉 getopt(3) 程序在报告错误时使用什么文件名(或程序名)。

    getopt 命令的 “-o” 选项所指定的选项字符串遵循如下规则:

    • 每一个字符代表一个选项;
    • 字符后跟一个冒号(:)表示选项需要一个参数;
    • 字符后跟两个冒号(::)表示选项有个可选参数。

    本文参考自 《Linux Shell命令行及脚本编程实例详解

    相关文章

      网友评论

        本文标题:选项处理(三)使用 getopt 处理多命令行选项

        本文链接:https://www.haomeiwen.com/subject/cjjjtxtx.html