在Bash shell指令碼編程中,如何正確無誤擷取到“指令碼選項參數”和“指令碼參數”呢?

來源:互聯網
上載者:User

標籤:位置變數   指令碼參數   選項參數   bashshell   指令碼   

    Linnux 中有些命令的功能非常強大,主要是因為它支援的命令選項比較多。如:【ip】命令可以配置IP地址、路由條目的組態管理操作非常完善,該命令就可以完成【ifconfig】和【route】命令實現的所有功能。函數是單獨的功能模組,如果函數能夠接收選項參數,那麼該函數的功能就變得豐富,且靈活。指令碼也是一樣。

那麼linux中命令的格式又是怎麼樣的呢?

[[email protected] ~]# command   [optons parameter1 | parameter2]...  parameter3  parameter3 ...                  命令      選項    選項參數                   命令參數(1)   命令參數(2)


我們書寫指令碼的標準:與linux中命令的格式幾乎一樣。那麼如果我們的指令碼支援選項參數,格式如下:

  scriptName   {-option|--option     parameter}...       scriptParameter ...   指令碼名稱      短選項  長選項       選項參數             指令碼參數

說明

     option                使用單杠(-)或雙杠(--)來表示選項。     parameter             選項參數     scriptParameter       指令碼參數


    這些選項、選項參數和指令碼參數都統稱為位置參數(positional parameter),shell會使用特殊的變數來記錄它們。所以在指令碼或函數中就可以使用這些變數來引用指令碼或函數的參數了。既然稱為位置參數,應該有前後順序。那麼bash shell是如何標識不同位置的參數的呢?

         $1           該變數記錄第1個參數 $2           該變數記錄第2個參數 $3           該變數記錄第3個參數 ...           .... $9           該變數記錄第9個參數 ${10}        該變數記錄第10個參數 ...          ...            $0           在命令列運行指令碼時:                           如果使用絕對路徑運行指令碼的話,記錄指令碼名稱時使用的是絕對路徑。                   如果使用相對路徑運行指令碼的話,記錄指令碼名稱時使用的是相對路徑。      可以使用: 【basename $0】方法去除指令碼的路徑。只擷取指令碼名稱。         $#           位置參數的個數 $*           擷取所有參數,把這些參數當做一個單詞處理。不允許使用 for 進行迭代。 [email protected]           也是擷取所有參數。把它當作一個字串。該字串中包含多個使用空間分              隔的單片語成,這種方式允許使用for 迭代出該字串中的              每一個單詞(位置參數)的。

那麼,我們在指令碼或函數中怎麼樣擷取選項參數呢?

    分析:書寫指令碼或函數時,如果支援選項參數的話,要遵循上述格式。選項option有一個特點:都使用單杠(-)或雙杠(--)來表示這就是指令碼或函數的選項。它後面跟就是選項參數了。這麼是如何?的呢?實現方式有兩種:

1、使用 if 判斷語句。

  if [[ "$1" =~ ^- ]];then      $2就是選項$1的參數了  fi


2、通過選擇結構的方式: case

   case $1 in      -a|--add)   $2就是選項$1的參數了   ;;   esac


     這種擷取指令碼或函數的選項參數的方式有太多的局限性。對於擷取只有一個選項的指令碼或函數有用。對於多個選項參數的指令碼/函數就無能為力了。

     雖然使用if的多支語句可以擷取多個選項的參數。要把每個選項都作為一條if的分枝語句,很繁瑣。


     如果,我們的指令碼或函數中要使用到多個選項。那麼怎麼擷取選項的各個參數呢?

bash shell 提供【shift】命令來協助操作命令列參數,該命令能夠改變命令列參數的相對位置。shift 預設將每個參數變數左移一個位置。

     如:假如給指令碼或函數傳遞了2個參數,每執行一次shift命令,變數$2的值移組變數$1,變數$1的值被丟棄。

shift 命令的使用

shift: shift [n]          設定步長。預設是為1 .

    我們使用【shift】命令與選擇語句 case 就可以很方便的取得每一個選項的參數了,而且也很簡潔。例:

mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /pa/file

  case $1 in       -D|--description)               該就選項的參數就是$2了                       shift 2;;       -A|--author)               該選項的參數就是$2了       shift 2;;*)               echo "Usage: 指令碼或函數的使用方法"   esac

    上述提取,指令碼/函數的選項參數的方法有問題:

無論運行指令碼mkscript時傳遞的參數正確也否都會顯示"echo "Usage: 指令碼或函數的使用方法".都會執行這一步。

    最理想的就是:如果使用者使用該指令碼的時候且帶了選項,如果“選項”不是 case 語句列出的“選項”就告訴使用者使用該指令碼或函數的方法。又能正確無誤地取得指令碼參數/pa/file.

分析:

    執行 case 選擇語句,要有一個條件:如果“參數”是"選項"才執行case語句。在指令碼中"選項"的標誌是:單杠(-)或雙杠(--),我們就可以根據該標誌判斷 case 選擇語句是否執行。

    因為,我們的指令碼選項很多,所以要使用到迴圈.判斷是否是”選項“作為迴圈的條件。我們把提取指令碼的選項參數和指令碼參數方法修改成如下

while [ "$1" != "${1##[--,-]}" ];do      case $1 in          -D|--description)              該選項的參數就是$2      shift 2      ;;  -A|--author)              該選項的參數就是$2      shift 2      ;;  *)              使用該指令碼時,雖然使用了選項,但是指令碼不支援的,都匹配 *      在這裡就可以提示使用者:指令碼的使用方法了      shift 2      ;;      esacdone                指令碼的參數=$1


本文出自 “Linux” 部落格,請務必保留此出處http://9528du.blog.51cto.com/8979089/1529634

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.