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

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

此脚本的运行效果如下:

选项处理(三)使用 getopt 处理多命令行选项_第1张图片
显示效果

此脚本中的 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 ] [-o ]"
        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 处理多命令行选项_第2张图片
显示效果
实例3

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

#! /bin/bash

vflag=off
output=""
filename=""

set -- `getopt hvf:o: "$@"`

function usage() {
        echo "USAGE:"
        echo "  myscript [-h] [-v] [-f ] [-o ]"
        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 处理多命令行选项)