shell脚本之shift和getopts篇中有提到getopts,除了bash自带的内部变量getopts外,util-linux-ng包还提供了一个工具getopt ,该工具较bash内置的getopts更强大,其不仅支持短参-s,还支持–longopt的长参数,甚至支持-longopt的简化参数。相较于getopts ,getopts 不但支持长短选项,其还支持选项和参数放在一起写。

一、getopt命令的用法

getopt [options] -o|–options optstring [options] [–] parameters
选项说明:

  • -a:使getopt长参数支持”-“符号打头,必须与-l同时使用
  • -l:后面接getopt支持长参数列表
  • -n program:如果getopt处理参数返回错误,会指出是谁处理的这个错误,这个在调用多个脚本时,很有用
  • -o:后面接短参数列表,这种用法与getopts类似
  • -u:不给参数列表加引号,默认是加引号的(不使用-u选项),例如在加不引号的时候 –longoption “arg1 arg2″ ,只会取到”arg1″,而不是完整的”arg1 arg2”

其有两种使用方法,如下

方法1:

 1ARGV=($(getopt -o 短选项1[:]短选项2[:]...[:]短选项n -l 长选项1,长选项2,...,长选项n -- "$@"))
 2for((i = 0; i < ${#ARGV[@]}; i++)) {
 3    eval opt=${ARGV[$i]}
 4    case $opt in
 5    -短选项1|--长选项1)
 6       process
 7       ;;
 8    # 带参数
 9    -短选项2|--长选项2)
10       ((i++));
11       eval opt=${ARGV[$i]}
12       ;;
13    ...
14    -短选项n|--长选项n)
15       process
16       ;;
17    --)
18       break
19       ;;
20    esac
21}

方法2:

 1ARGV=($(getopt -o 短选项1[:]短选项2[:]...[:]短选项n -l 长选项1,长选项2,...,长选项n -- "$@"))
 2eval set -- "$ARGV"
 3while true
 4do
 5    case "$1" in
 6    -短选项1|--长选项1)
 7        process
 8        shift
 9        ;;
10    -短选项2|--长选项2)
11        # 获取选项
12        opt = $2
13        process
14        shift 2
15        ;;
16    ......
17    -短选项3|--长选项3)
18        process
19        ;;
20    --)
21break
22;;
23esac
24}

注意:如果getopt命令本身没有使用-o|–option选项的话,那么–后面的第一个参数被当做短选项。

二、示例

 1#!/bin/bash
 2# A small example program for using the new getopt(1) program.
 3# This program will only work with bash(1)
 4# Note that we use `"$@"' to let each command-line parameter expand to a
 5# separate word. The quotes around `$@' are essential!
 6# We need TEMP as the `eval set --' would nuke the return value of getopt.
 7TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: -n 'example.bash' -- "$@"`
 8if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
 9# Note the quotes around `$TEMP': they are essential!
10eval set -- "$TEMP"
11while true ; do
12        case "$1" in
13                -a|--a-long) echo "Option a" ; shift ;;
14                -b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;
15                -c|--c-long)
16                        # c has an optional argument. As we are in quoted mode,
17                        # an empty parameter will be generated if its optional
18                        # argument is not found.
19                        case "$2" in
20                                "") echo "Option c, no argument"; shift 2 ;;
21                                *)  echo "Option c, argument \`$2'" ; shift 2 ;;
22                        esac ;;
23                --) shift ; break ;;
24                *) echo "Internal error!" ; exit 1 ;;
25        esac
26done
27echo "Remaining arguments:"
28for arg do echo '--> '"\`$arg'" ; done 

运行结果如下:

 1[root@361way bash]# sh get.sh -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "
 2Option a
 3Option c, no argument
 4Option c, argument `more'
 5Option b, argument ` very long '
 6Remaining arguments:
 7--> `par1'
 8--> `another arg'
 9--> `wow!*\?'
10使用eval 的目的是为了防止参数中有shell命令,被错误的扩展。
11
12平时使用时,可以使用的样例为:
13
14ARGS=`getopt -a -o I:D:T:e:k:LMSsth -l instence:,database:,table:,excute:,key:,list,master,slave,status,tableview,help -- "$@"`
15[ $? -ne 0 ] && usage
16#set -- "${ARGS}"
17eval set -- "${ARGS}"
18while true
19do
20        case "$1" in
21        -I|--instence)
22                instence="$2"
23                shift
24                ;;
25        -D|--database)
26                database="$2"
27                shift
28                ;;
29        -T|--table)
30                table="$2"
31                shift
32                ;;
33        -e|--excute)
34                excute="yes"
35                shift
36                ;;
37        -k|--key)
38                key="$2"
39                shift
40                ;;
41        -L|--list)
42                LIST="yes"
43                ;;
44        -M|--master)
45                MASTER="yes"
46                ;;
47        -S|--slave)
48                SLAVE="yes"
49                ;;
50        -A|--alldb)
51                ALLDB="yes"
52                ;;
53        -s|--status)
54                STATUS="yes"
55                ;;
56        -t|--tableview)
57                TABLEVIEW="yes"
58                ;;
59        -h|--help)
60                usage
61                ;;
62        --)
63                shift
64                break
65                ;;
66        esac
67shift
68done