編寫一個shell腳本,做一些事;改進這個腳本,更好做這件事;再改進這個腳本,幫自己做些其他的事情;再改進這個腳本幫助其他人做一些事......
簡單的腳本處理,一般使用變量$0 $1 $2 ...就可以依次獲得全部參數,還可以通過$#獲得這個腳本一共有多少個參數。如果你需要處理的情況(或者分支)更多的時候,這個方法就不湊效了,這時候,就可以考慮使用getopts了(man getopts)。
在使用getopts命令的時候,shell會自動產生兩個變量OPTIND和OPTARG。
OPTIND初始值爲1,其含義是下一個待處理的參數的索引。只要存在,getopts命令返回true,所以一般getopts命令使用while循環;
OPTARG是當getopts獲取到其期望的參數後存入的位置。而如果不在其期望內,則$optname被設爲?並將該意外值存入OPTARG; 如果$optname需要擁有具體設置值而實際卻沒有,則$optname被設爲:並將丟失設置值的optname存入OPTARG;
對於$optname,可以用後標:來表示是否需要值;而前標:則表示是否開啓靜默模式。
這裏將通過一個示例來介紹getopts的用法。
下面的代碼,可以通過"./sample -d 5"的方式獲取參數:
- vi sample.sh
- #!/bin/sh
- day=7 #default value
- while getopts ":d:" opt; do
- case $opt in
- d)
- day=$OPTARG #get the value
- ;;
- ?)
- echo "How to use: $0 [-d DAY]" >&2
- exit 1
- ;;
- :)
- echo "Option -$OPTARG requires an argument." >&2
- exit 1
- ;;
- esac
- done
- echo $day
上面例子中需要解釋的是下面的部分:
- while getopts ":d:" opt; do
這裏,第一個冒號表示忽略錯誤(例如出現了不認識的參數),並在腳本中通過::)來處理這樣的錯誤;字母d則表示,接受參數-d;d後面的冒號表示 參數d接收值,即“-d 7”這樣的形式;(這裏opt變量,可以在while循環中引用當前找到的參數,試試輸出$opt試試)
如果是要有很多參數,那麼寫法可能是:
- while getopts ":ixarm:uneh" opt; do
- #!/bin/bash
- echo "OPTIND starts at $OPTIND"
- while getopts ":pq:" optname
- do
- case "$optname" in
- "p")
- echo "Option $optname is specified"
- ;;
- "q")
- echo "Option $optname has value $OPTARG"
- ;;
- "?")
- echo "Unknown option $OPTARG"
- ;;
- ":")
- echo "No argument value for option $OPTARG"
- ;;
- *)
- # Should not occur
- echo "Unknown error while processing options"
- ;;
- esac
- echo "OPTIND is now $OPTIND"
- done