Linux Bash Shell學習(十四):命令列選項

來源:互聯網
上載者:User

  本文也即《Learning the bash Shell》3rd Edition的第六章Command-Line Options and Typed varilables之讀書筆記之一,但我們將不限於此。

  在Linux命令中經常帶有參數例如[-option]等等。在命令列中可能有0個或者多個這些選項。我們在之前學習了位置參數,包括$1,$2,$3…,$*,$#,參見Linux Bash Shell學習(七):shell編程基礎——運行Shell指令碼、function
。這些位置參數都是唯讀。

移位Shift

  shift提供對唯讀位置參數的移位賦值的操作,將1=$2,2=$3,…,可以使用shift N來制定移位的數目,例如shift 3,則表示1=$4,2=$5,…。如果命令列中有[-options]的,我們可以對他們進行判斷,並進行移位處理。一個簡單例子如下:

if [ $1 = -o ]; then


   
[process the -o option] 



    shift

fi


[normal processing of arguments...]

  下面給兩個例子,介紹如何用shift來檢查參數。

#例子一:有可能有-N的參數,且為第一參數。如果第一個參數是-N,記錄在howmany中,進行shift,將$2置於$1的位置,如果第一個參數是-X,但X不是數字,給出警告語句,否則howmany使用預設的-10。

function test1

{

    #對於grep,^表示從匹配行首,$表示匹配行尾,在這裡表示整個$1匹配,而不是部分匹配,*表示前面的字元匹配0個或者多個,下面[0-9]*即表示後面跟著0個或者多個數字,[0-9][0-9]*表示數字後面有0個或多個數字。故echo $1 | grep '^-[0-9][0-9]*$'表示匹配格式-N,N為數字。grep的具體用法看參見http://www.yesadmin.com/301/135287/index.html
 
    #$(command)表示命令執行的內容。

    #-n str,字串不為null,長度大於零

    #請注意雙引號的使用,表示這是一個需要檢查的str
   
    if [ -n "$(echo $1 | grep '^-[0-9][0-9]*$')"
]; then

        howmany=$1

       shift


    elif [ -n "$(echo $1 | grep '^-')" ]; then

        echo 'usage: test1 [-N] filename'


        exit 1

    else

        howmany="-10"

    fi

    echo "sort -nr $1 | head $howmany"

}

test1 -5 $file

  對於多個參數,也假設只能放在其他參數之前,如下。對於-b的選項,帶自己的參數即[-b barg],對於-b需要多移一位。

while [ -n "$(echo $1 | grep '-')" ]; do

    case $1 in

        -a ) [process option -a]
;;


        -b ) [process option –b, $2 is the option's argument]
 

              shift
;;

        -c ) [process option -c]
;;


        *  ) echo 'usage: alice [-a] [-b barg] [-c] args...'


             exit 1


    esac

    shift

done

[normal processing of arguments...]

  但是這種方式不能解決下面兩個問題:一、無法使用-abc來代替-a –b -c,二、無法使用-barg來代替-b arg,但是這兩種方式在Linux命令中都是比較常見的。我們可以使用getopts這個built-in的命令來處理:

getopts

  getopts有兩個參數,第一個參數是一個字串,包括字元和“:”,每一個字元都是一個有效選項,如果字元後面帶有“:”,表示這個字元有自己的參數。getopts從命令中擷取這些參數,並且刪去了“-”,並將其賦值在第二個參數中,如果帶有自己參數,這個參數賦值在“OPTARG”中。下面是例子採用getopts的寫法。我們將它寫成一個可執行檔例子。

echo "---Test 3---"


function test3

{

    echo "test3 $@"


    #OPTIND記錄準備分析(即下一次分析)的第幾個參數,如果我們不使用function,而是直接作為指令碼,每次執行OPTIND將重新初始化,但是如果我們使用function的方式,OPTIND將保持上次的值,即getopts接著分析第N個參數,例如第5個參數,所以需要unset,以保證正確。如果我們用-ab表示-a -b,當分析完-a之後,OPTIND並不加一,保持原值,下次仍然分析該位置參數,如果-b arg,則OPTIND加二。所以我們不需要在getopts中進行shift,可以在完成所有getopts分析後,統一進行shift $(($OPTIND - 1))


    echo "OPTIND=$OPTIND"


    unset OPTIND

    #如果我們使用"ab:c",如果option並非所需,則報告illegal option —d之類的,如果我們去掉相關資訊,getopts的第一個參數以":"開頭即可。當然也可以通過設定環境參數OPTERR為0,如果不匹配,則將擷取的參數值置為"?",在下面中case的第四個選擇可以為/?)或者*)。

    while getopts ":ab:c" opt
; do

        echo -n "OPTIND=$OPTIND : "


        case $opt in

            a  ) echo "process option -$opt" ;;

            b  ) echo "process option -$opt, $OPTARG is the option's argument" ;;

            c  ) echo "process option -$opt" ;;

            #下面等同於 *) ,因為將opt設定為"?"


            /?  ) echo "process option -$opt"

                   echo 'usage: alice [-a] [-b barg] [-c] args...'

                   exit 1

        esac

    done

    echo "OPTIND=$OPTIND, shift $(($OPTIND - 1))"

    shift $(($OPTIND - 1))


    echo "test $@"

    echo "normal processing of arguments..."

}

test3 -b hello -a -c ok

echo

test3 -bhello -ac ok

echo

test3 -ab hello ok

echo

test3 -d

  如果命令的參數都採用選項的方式,getopts就可以提供很靈活的分析方式。另外對於非匹配選項,也即"?"的選項,也可以擷取命令的參數,可以根據$((OPTIND-1))獲得該位置參數的位置,繼而擷取該參數的具體內容。

相關連結: 我的Linux操作相關文章

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.