天天看点

shell编程——如何实现命令行选项的各种个性功能如何实现命令行选项的各种个性功能

如何实现命令行选项的各种个性功能

在前面

命令行选项的那些事

中介绍了几种有"个性"的选项功能,包括:

  • 选项依赖:例如"-a"或"--add"要依赖于"-m"或"--manage"选项
  • 选项互斥:例如"-a"或"--add"与"-r"或"--remove"是互斥的
  • 识别负数参数:例如

    -w -5 -3 5

    ,其中-5和-3不是短选项,而是负数参数
  • 模式化选项:例如

    script_name MODE OPTIONS

    的MODE部分,可以是manage模式(--manage,-m),也可以使用add模式(--add,-a)
  • 选项参数替代选项:例如

    head -n 3

    可以替换为

    head -3

这里介绍下用getopt解析参数后实现它们的思路。

在getopt解析完成后,假设返回结果保存到了

$parameters

变量中。

1.选项依赖性

这个其实很好实现,只需使用grep对

$parameters

变量进行筛选一下即可。

例如实现依赖性,只需:

{ echo "$parameters" | grep -E '\-\-add|\-a ' | grep -E '\-\-manage|\-m '; } &>/dev/null
[ $? -ne 0 ] && exit           

2.选项互斥性

要实现互斥性,只需:

or_op=`echo "$parameters" | grep -Eo '\-\-add|\-a | \-\-remove|\-r ' | wc -l`
[ "$or_op" = "2" ] && exit           

3.识别负数参数

前面解释过,getopt提供了两种扫描模式,只要使用

+

扫描模式,就能轻松区别负数参数和短选项。

4.模式化选项

一般来说,模式化选项都是命令行的第一个参数。所以,只需将

$parameter

中"--"后面的第一个非选项类型的参数提取出来,就是所谓的模式了。当然,还得对这个参数进行一些判断,避免它不是模式参数。

例如,要提供addr、show、route三种模式,那么其它的非选项类型参数值都不应该是模式参数。

eval set -- "$parameters"
while true ; do
    case "$1" in
            ...
        --) 
            shift
            [ "$x" = "addr" -o "$x" = "route" -o "$x" = "show" ] && MODE=$1
            shift
            break ;;
        *) echo "wrong";exit 1;;
    esac
done           

5.选项参数替代选项

就以

-n3

-3

为例,它的通用格式是

-n NUM

-NUM

。这个并不好实现,我能想到的方法是将这个

-NUM

先从

$@

中筛选出来,然后赋值。

NUM=`echo "$@" | grep -Eo "\-[0-9]+"`
ARGS=`echo "$@" | sed -nr 's!(.*)-[0-9]+(.*)!\1\2!'p`
eval set -- "$ARGS"