getopts
格式
1 #!/bin/bash
2 echo "begin index is $OPTIND"
3 echo "begin ARG is $OPTARG"
4
5 while getopts ":ab:c:" OPT
6 do
7 case $OPT in
8 a)
9 echo "\$OPTIND=$OPTIND, a is $OPTARG, \$1=$1, \$OPTIND=$OPTIND";;
10 b)
11 echo "\$OPTIND=$OPTIND, b is $OPTARG, \$2=$2, \$OPTIND=$OPTIND";;
12 c)
13 echo "\$OPTIND=$OPTIND, c is $OPTARG, \$3=$3, \$OPTIND=$OPTIND";;
14 :)
15 echo "\$OPTIND=$OPTIND, : is $OPTARG, \$#=$@, \$OPTIND=$OPTIND";;
14 ?)
15 echo "\$OPTIND=$OPTIND" # OPTIND 已經指向下一個參數
16 shift $(($OPTIND-2)) # -2 纔可以讓當前參數位於 $1
17 echo "剩餘參數列表:$@"
18 echo -e "Illegal option -- '$1' \nUsage: `basename $0` [-a] [-b value] [-c value] args"
19 exit 2 ;;
20 esac
21 done
22 echo "end index is $OPTIND"
lfp@legion:~$ ./bin/getopts.sh -b bb -c cc -d 22 -a
begin index is 1 # 初始值爲1
begin ARG is # 沒有初始值
$OPTIND=3, b is bb, $2=bb, $OPTIND=3
$OPTIND=5, c is cc, $3=-c, $OPTIND=5
$OPTIND=6
剩餘參數列表:-d 22 -a
Illegal option -- '-d'
Usage: getopts.sh [-a] [-b value] [-c value] args
區別 選項列表 參數列表
選項列表
命令可以接收的選項
參數列表
命令行中,除命令之外的字符組成參數列表。
./bin/getopts.sh -b bb -c cc -d 22 -a 參數列表爲 -b bb -c cc -d 22 -a,對應的位置從1開始計算 選項的位置 -b(1),-c(3) 。因爲-b帶參數,所以OPTIND需要加2才能指向下一個選項, 由此可知,不帶參數的選項,OPTIND只需要加1即可
getopts 從命令行前面開始處理。參數列表中包括選項和參數,選項通過
-
來區分,其他被視作選項的參數標準格式 while getopts "選項列表" OPT
選項列表字符串
- 前面加冒號
:
則表示當遇到選項列表之外的選項時,不會有警告信息(靜默模式)- 一個字母代表一個選項
- 選項後面跟冒號
b:
表示該選項b,需要指定參數- 選項後面沒有冒號
ab:
表示該選項a,不需要指定參數,也稱作開關選項OPT
代表輸入的參數
如果出現了選項列表之外的選項,OPT 會被設置爲
?
如果缺少參數,分兩種情況
如果選項列表前面加冒號(靜默模式),則OPT被設置爲
:
(如果此時沒有:
匹配,則會匹配到?
)如果沒加,則OPT被置爲
?
case
- 最後一個選擇——?,表示如果出現了選項列表之外的選項,進行的操作
getopts 提供的兩個常量
OPTARG
表示當前選項的參數
OPTIND
表示下一個選項在【參數列表】中的位置,參數列表的初始值爲1(即從$1開始)
處理帶參數的選項,值加2;處理不帶參數的選項或非法選項,值加1
在case匹配開始的時候就已經增加,指向了下一個選項的位置
shift $(($OPTIND-2)) 讓當前選項(正在處理的選項)處於 $1 位置
shift $(($OPTIND-1)) 讓下一個選項(未處理的選項)處於 $1 位置
shift
用來左移【參數列表】,shift 2 表示將參數列表中前2個左移(丟棄)
特點
-
Shell 內建命令
-
getopts不支持長選項。如 --help
-
輸入選項參數的格式必須是
-o arg
參數緊跟選項,中間有空格 -
處理完一個選項後,OPTIND會自動指向下一個選項。
-
不會重排所有參數的順序
-
帶參數的選項要放在不帶參數的選項(開關選項)之前,或者開關選項後面不能帶參數
# 可以識別 -a 只是沒有參數 lfp@legion:~$ ./bin/getopts.sh -a -b bb -c cc -d begin index is 1 begin ARG is $OPTIND=2, a is , $1=-a, $OPTIND=2 $OPTIND=4, b is bb, $2=-b, $OPTIND=4 $OPTIND=6, c is cc, $3=bb, $OPTIND=6 $OPTIND=7 剩餘參數列表:-d Illegal option -- '-d', Usage: getopts.sh [-a] [-b arg] [-c arg] file ...
-
遇到非
-
開頭的參數或選項結束標記--
,則終止# -- 選項結束 lfp@legion:~$ ./bin/getopts.sh -b bb -c cc -- -d -a begin index is 1 begin ARG is $OPTIND=3, b is bb, $2=bb, $OPTIND=3 $OPTIND=5, c is cc, $3=-c, $OPTIND=5 end index is 6 # 非 - 開頭的參數 # 選項a不帶參數,aa被識別爲非-開頭的參數 lfp@legion:~$ ./bin/getopts.sh -a aa -b bb -c cc -d begin index is 1 begin ARG is $OPTIND=2, a is , $1=-a, $OPTIND=2 end index is 2
-
遇到非法選項,則後面的選項參數都無法獲取
# -d 非法選項 lfp@legion:~$ ./bin/getopts.sh -b bb -d -c cc -a begin index is 1 begin ARG is $OPTIND=3, b is bb, $2=bb, $OPTIND=3 ./bin/getopts.sh: 非法選項 -- d # 可以通過在選項列表字符串前面加冒號來取消 $OPTIND=4 剩餘參數列表:-d -c cc -a Illegal option -- '-d', Usage: getopts.sh [-a] [-b arg] [-c arg] file ...
-
如果缺少參數
# 會把後面的 -c 選項當做參數,然後遇到 -c 選項的參數(非-開頭的選項,終止) lfp@legion:~$ ./bin/getopts.sh -b -c cc -a begin index is 1 begin ARG is $OPTIND=3, b is -c, $2=-c, $OPTIND=3 end index is 3
-
如果選項和參數之間沒有空格
lfp@legion:~$ ./bin/getopts.sh -bbb -c cc -a begin index is 1 begin ARG is # 可以拿到選項的值,但是 OPTIND 只加1,按無參數選項處理的 $OPTIND=2, b is bb, $2=-c, $OPTIND=2 $OPTIND=4, c is cc, $3=cc, $OPTIND=4 $OPTIND=5, a is , $1=-bbb, $OPTIND=5 end index is 5