0. 序

由于应用的特殊性以及七网隔离, 某些功能只能在预发或者线上机器执行JMX来进行测试, JMX方法的入参是一个String,传入的值为json格式的文件路径.

这样使用了一段时间之后,发现当需要频繁修改json内容时,就显得太繁琐了.我需要vim打开文件,修改json串,然后保存退出,再使用curl来调用JMX.

于是打算写个支持长短选项的shell脚本来提高一下效率

1. shell脚本的传参方式

我们写shell脚本,一般的传参方式有3种

  • 手工处理方式:example.sh argv1 argv2
  • getopts(不支持长选项):example.sh -a -b value2
  • getopt(支持长选项):example.sh -a -b value2 –argv3 value3

下面分别对这3种方式进行一个使用介绍

2. 手工处理方式

这种方式,一般也是简单脚本里面最常用的,例如

example.sh argv1 argv2 argv3

一般取这种方式的入参,有下面几个点需要注意一下

  • $0:指命令本身,如上面的example.sh
  • $1:第一个入参,后续入参数字依次递增
  • $#:入参总的个数,不包括命令本身
  • $@:入参列表,不包括命令本身
  • $* :和$@相同,但”$” 和 “$@”(加引号)并不同,”$“将所有的参数解释成一个字符串,而”$@”是一个参数数组

这种方式的入参,所有的入参解析工作都交由脚本编写人员来处理,可以起到灵活多变的高度,但是处理起来比较累,所以这种方式一般用在比较简单的脚本上.

3. getopts

处理命令行参数是一个相似而又复杂的事情,而在shell中,我们可以使用getopts和getopt来简化这件事.

getopts是内置在bash中的,它不支持长选项,getopt是独立的可执行文件,它支持长选项.

下面介绍一下getopts的用法.

example.sh -a -b value2

比如上面的命令,我们指定了两个短选项,分别是-a和-b,其中-a是不带参数值的,而-b是带参数值的,那么如何定义短选项是否需要参数呢

向上面这样的脚本,我们一般是这么定义入参的:

getopts "ab:"

我们看到b后面跟了一个冒号,而a没有,是的,shell里面用来区分短选项是否需要参数,就是通过冒号来进行的

  • 后面没有冒号,表示选项不接参数
  • 后面有一个冒号,表示选项必须接参数

下面是一个完整的示例脚本:

#!/bin/bash

while getopts "ab:" arg #选项后面的冒号表示该选项需要参数
do
        case $arg in
             a)
                echo "i am a"
                ;;
             b)
                echo "i am b, my value is $OPTARG" #参数存在$OPTARG中
                ;;
        esac
done

4. getopt

绝大多数脚本使用getopts应该就可以满足需求了,如果需要支持长选项以及可选参数,那么就需要使用getopt了.

getopt和getopts类似,也是通过冒号来区分选项是否接受参数值,其定义如下:

  • 后面没有冒号,表示选项不接参数
  • 后面有一个冒号,表示选项必须接参数
  • 后面有两个冒号,表示选项参数可选

我们来看一下这个命令

example.sh -a -b value2 --argv3 value3

我们看到这个命令有两个短选项和一个长选项,分别是-a,-b和–argv3,其中a不接收参数,b和argv3接收参数,我们看一下如何在脚本里面进行定义

ARGS=`getopt -o ab: -l "argv3:,help"  -- "$@"`
eval set -- "${ARGS}"

因为getopt是一个独立的程序,所以我们使用``来进行getopt的执行和结果获取,并通过eval set将规范化后的命令行参数分配至位置参数($1,$2,…)

其中-o或–options选项后面接可接受的短选项;-l或–long选项后面接可接受的长选项,用逗号分开

一个完整的示例脚本如下:

#!/bin/bash

ARGS=`getopt -o ab: -l "argv3:,help" -- "$@"`
eval set -- "${ARGS}"

while true;
do
    case "$1" in
        -a) 
            echo "i am a"
            shift
            ;;
        -b) 
            echo "i am b, my value is $2" 
            shift 2
            ;;
        --argv3)
            echo "i am argv3, my value is $2"
            shift 2
            ;;
        --help)
            echo "i am help info"
            exit 0
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Internal error!"
            exit 1
            ;;
    esac
done


blog comments powered by Disqus

Published

15 April 2015

Category

program