[sh]getopt参数解析

时间:2024-12-31 09:37:38

https://www.cnblogs.com/FrankTan/archive/2010/03/01/1634516.html

sh参数处理方法

    * 手工处理方式
* getopts #好像不支持长选项,但更简单点
* getopt # 支持长选项
    *    $0 : ./test.sh,即命令本身,相当于C/C++中的argv[0]
* $1 : -f,第一个参数.
* $2 : config.conf
* $3, $4 ... :类推。
* $# 参数的个数,不包括命令本身,上例中$#为4.
* $@ :参数本身的列表,也不包括命令本身,如上例为 -f config.conf -v --prefix=/home
* $* :和$@相同,但"$*" 和 "$@"(加引号)并不同,"$*"将所有的参数解释成一个字符串,而"$@"是一个参数数组。如下例所示:

1.参数&选项 optstring parameters

-f为选项,它需要一个参数,即config.conf
-v 也是一个选项,但它不需要参数
--prefix长选项,可以是等号,也可以是空格. ./test.sh -f config.conf -v --prefix=/home
./test.sh -f config.conf -v --prefix /home
./test.sh -a -b -c                :短选项,各选项不需参数
./test.sh -abc :短选项,和上一种方法的效果一样,只是将所有的选项写在一起。 ./test.sh -a args -b -c :短选项,其中-a需要参数,而-b -c不需参数。
./test.sh --a-long=args --b-long :长选项

getopt参数说明

TEMP=getopt -o ab:c:: --long a-long,b-long:,c-long:: -n 'example.bash' -- "$@"

  1. -o表示短选项
  2. --long表示长选项
  3. 一个冒号表示有参数
  4. 两个冒号表示该选项有一个可选参数,可选参数必须紧贴选项,如-carg 而不能是-c arg
比如我们使用
./test -a -b arg arg1 -c 你可以看到,命令行中多了个arg1参数,在经过getopt和set之后,命令行会变为:
-a -b arg -c -- arg1
$1指向-a,$2指向-b,$3指向arg,$4指向-c,$5指向--,而多出的arg1则被放到了最后。 while循环这个参数列表: 逐次裁掉参数, arg1裁掉-a --> -b arg -c -- arg1
$1指向了-b, $2指向了arg

一个例子

TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: -n 'example.bash' -- "$@"`

eval set -- "$TEMP"

while true ; do
echo "-------: $1"
case "$1" in
-a|--a-long) echo "Option a" ; shift ;; # -a -b arg -c -- arg1裁掉-a --> -b arg -c -- arg1
-b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;; # -b arg -c -- arg1 裁掉-b arg--> -c -- arg1
-c|--c-long)
# c has an optional argument. As we are in quoted mode,
# an empty parameter will be generated if its optional
# argument is not found.
case "$2" in
"") echo "Option c, no argument"; shift 2 ;;
*) echo "Option c, argument \`$2'" ; shift 2 ;;
esac ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done

达到这样的目的: ./start --delay=10

DELAY=60
# read the options
TEMP=`getopt -o d: --long delay:,ServerID:,appname: -n 'test.sh' -- "$@"`
echo $TEMP
eval set -- "$TEMP" while true ; do
case "$1" in
-d|--delay) DELAY=$2 ; shift 2 ;;
--ServerID) ServerID=$2 ; shift 2 ;;
--appname) appname=$2 ; shift 2 ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done sleep ${DELAY}

https://blog.****.net/wh211212/article/details/53750366

http://blog.51cto.com/1008305/1152722