歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> SHELL編程

使用getopts處理shell中的輸入參數

在編寫shell腳本中,經常要處理一些輸入參數,在使用過程中發現getopts更加方便,能夠很好的處理用戶輸入的參數和參數值。

getopts用於處理用戶輸入參數,舉例說明使用方法:

while getopts :a:b:cdefg opt; do

    case $opts in

        a) do sth;

  ......

        cde) do another;

    esac

done

幾個重要變量:

OPTIND:getopts使用OPTIND作為索引,來處理下一個需要處理的參數,記錄當前的狀態。

OPTARG:在上面的循環中,a,b兩個參數後面各有一個冒號,冒號表示該輸入的參數後面還有一個參數值,當getopts發現冒號後,會處理用戶輸入的參數值,這個參數值被保存在OPTARG中。

OPTSTRING:也就是上例中的 :a:b:cdefg,getopts需要處理的參數。注意,最前面的冒號“:”用於指定getopts工作於silent mode,在silent模式下,當用戶輸入的參數不滿足OPTSTRING時,不會講illegal option這樣的錯誤信息打印出來,使代碼看起來更加專業。如果想要工作在verbose模式下,可以去掉最前面的冒號

下面,簡單的寫了一個shell腳本用來描述getopts的使用方法:

#! /bin/bash
 function c1() {
 cmd="rhc app create -p RedHat"
while getopts  :a:t:sn opt; do
    case $opt in
        a) cmd=$cmd" -a $OPTARG" ;;
        t) cmd=$cmd" -t $OPTARG" ;;
        s) cmd=$cmd" -s" ;;
        n) cmd=$cmd" -n --no-dns" ;;
        \?) echo "Invalid param" ;;
    esac
done
echo $cmd
 }

 c1 -a app1 -t perl-5.10 -s -n

執行這個腳本,我們就會得到預期的結果

[root@linuxidc shell]# ./getopts-silent.sh
 rhc app create -p redhat  -a app1 -t perl-5.10 -s -n  --no-dns

當然,有些時候,我們更新網將function寫入.bashrc中,方便自己隨時調用,如果將這段代碼直接粘貼到.bashrc中,可能會引起問題:我沒有得到預期的結果,腳本中的cmd並沒有按照預想的情況得到處理,這是因為什麼呢?

原因在於,保存在.bashrc後,第一次執行完成後,下一次在執行時,OPTIND不會重新產生,因為他被作為一個global variable使用,所以getopts在調用時,他的索引會變得混亂。在腳本中執行沒有遇到這個問題的原因也在此,因為腳本每次執行時,都會調用一個 新的shell,所以OPTIND會被設置為1。如果想要他在.bashrc中生效,必須要在最上面加上local OPTIND

讓我們來稍微修改一下:


 
# Create apps
 function create-apps() {
    local OPTIND
    cmd="rhc app create -p $OPENSHIFT_PASSWD"
    while getopts a:t:sn x
    do
        case $x in
            a) cmd=$cmd" -a $OPTARG" ;;
            t) cmd=$cmd" -t $OPTARG" ;;
            s) cmd=$cmd" -s" ;;
            n) cmd=$cmd" -n --no-dns" ;;
            \?) echo Invalid Params ;;
        esac
    done
    echo $cmd
 }

source之後,我們可以直接調用,看一下是否達到了我們預期的結果:

[root@linuxidc shell]# create-apps -a free -t jbsseap -n
rhc app create -p redhat -a free -t jbsseap -n --no-dns

如果還不是很了解,你可以簡單的看下這個例子,這個例子是如果傳遞進來的參數包括f,那麼執行對應代碼:

while getopts "dfiPRrvW" opt      //賦值給opt
      do
        case $opt in
            f)                      //如果傳遞進來是f
              exec $realrm "$@"
                ;;
            *)
             
              # do nothing      //傳遞其他參數,包括d,i,p,r,v,w
                ;;
        esac
      done

Copyright © Linux教程網 All Rights Reserved