對 getopts 的理解

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個左移(丟棄)

特點

  1. Shell 內建命令

  2. getopts不支持長選項。如 --help

  3. 輸入選項參數的格式必須是 -o arg 參數緊跟選項,中間有空格

  4. 處理完一個選項後,OPTIND會自動指向下一個選項。

  5. 不會重排所有參數的順序

  6. 帶參數的選項要放在不帶參數的選項(開關選項)之前,或者開關選項後面不能帶參數

    # 可以識別 -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 ...
    
  7. 遇到非-開頭的參數或選項結束標記--,則終止

    # -- 選項結束
    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
    
  8. 遇到非法選項,則後面的選項參數都無法獲取

    # -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 ...
    
  9. 如果缺少參數

    # 會把後面的 -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
    
  10. 如果選項和參數之間沒有空格

    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
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章