shell 命令行实现
說明:原文網址http://blog.chinaunix.net/uid-26807463-id-3151601.html
獲取UNIX類型的選項:
unix有一個優點就是標準UNIX命令在執行時都具有相同的命令行格式:
command?-options?parameters
如果在執行Shell程序也采用上述格式,Bourne?Shell中提供了一條獲取和處理命令行選項的語句,即getopts語句。該語句的格式為:
getopts?option_string?variable
其中option_string中包含一個有效的單字符選項。若getopts命令在命令行中發現了連字符,那么它將用連字符后面的字符同?option_string相比較。若有匹配,則把變量variable的值設為該選項。若無匹配,則variable設為?。當getopts發現連字符后面沒有字符,會返回一個非零的狀態值。Shell程序中可以利用getopts的返回值建立一個循環。
有時侯選項中還帶一個值,getopts命令同樣也支持這一功能。這時需要在option_string中選項字母后加一個冒號。當?getopts命令發現冒號后,會從命令行該選項后讀取該值。若該值存在,那么將被存在一個特殊的變量OPTARG中。如果該值不存在,getopts命令將在OPTARG中存放一個問號,并且在標準錯誤輸出上顯示一條消息。
optstring??option字符串,會逐個匹配
varname?????每次匹配成功的選項
arg?????????????參數列表,沒寫時它會取命令行參數列表
$OPTIND?????特殊變量,option?index,會逐個遞增,?初始值為1
$OPTARG????特殊變量,option?argument,不同情況下有不同的值
細則1:
當optstring以”:“開頭時,getopts會區分invalid?option錯誤和miss?option?argument。?invalid?option錯誤時,varname會被設成?,$OPTARG是出問題的option;miss?option?argument時,varname會被設成:(在我的fedora系統里測試OPTARG為?),$OPTARG是出問題的option.
當optstring不以”:“開頭,invalid?option錯誤和miss?option?argument錯誤都會使varname被設成?,?$OPTARG是出問題的option(在我的fedora系統里測試OPTARG為空).
細則2:
當optstring中的字母跟”:“時,表明該option可接參數,參數(argument)放在$OPTARG中,如果缺參數,且optstring是以”:“開頭,則varname的值會是:(在我的fedora系統里測試OPTARG為?),$OPTARG是該option,?否則varname的值是?,$OPTARG是該option.(參照細則1)(在我的fedora系統里測試OPTARG為空)
1?#!/bin/bash??
2?if?[[?$#?-lt?1?]];then??
3?????echo?"USAGE:`basename?$0`?[-a]?[-b?value]?[-c]"??
4?????exit?1??
5?fi????
6????
7?while?getopts?:ab:c?name??
8?do??
9?????case?$name?in??
10?????????a)??aflag=1??
11?????????echo?"a"??
12?????????;;??
13?????????b)??bflag=1??
14???
15?????????if?[[?${OPTARG:0:1}?=?"-"?]];?then??
16?????????????echo?"invalid?parameter?of?$OPTARG"??
17?????????????exit?1??
18?????????fi??
19???
20?????????bval=$OPTARG??
21?????????;;??
22?????????c)??cflag=1??
23?????????echo?"c"??
24?????????;;??
25?????????\?)?echo?"Invalid?option?:`basename?$0`?[-a]?[-b?value]?[-c]"??
26?????????exit?1??
27?????????;;??
28?????????:)?echo?"$0:Must?supply?an?argument?to?-$OPTARG."??
29?????????exit?1??
30?????????;;??
31?????esac??
32?done??
33?echo?$bval??
在getopts分析選項時,如果-b后面不帶參數,直接跟-c的話,那么-c將作為-b的參數。
下面是一個簡單例子(腳本為getopt):
#/bin/bash
echo?$0
echo?$*
while?getopts?":a:bc"?opt
do
????????case?$opt?in
????????????????a?)
????????????????????????echo?$OPTARG????????????????????
????????????????????????echo?$OPTIND;;
????????????????b?)
????????????????????????echo?"b?$OPTIND";;
????????????????c?)
????????????????????????echo?"c?$OPTIND";;
??????????????????)
????????????????????????echo?"error"????????????????????
????????????????????????exit?1;;
????????????????esac
done
echo?$OPTIND
echo?$*
shift?$(($OPTIND?-?1))
echo?$*
echo?$0
運行sh?getopt.sh??-a?12?-b?-c?34?-m
輸出:
getopt.sh
-a?12?-b?-c?34
12
3
b?4
c?5
5
-a?12?-b?-c?34
34
getopt.sh
可以得出一些結論:
1、$0在用sh?或者?./執行腳本時,指的是腳本名,用source或.執行時,永運是bash,這也反應了sh?或者?./執行腳本的原理和source的方式是不同的.
2、$1?(1....n)指的第一個參數到....第n個參數
3、OPTARG存儲相應選項的參數?OPTIND指向的是下一個參數的index
4、shift?會改變參數的順序,通過左移去掉某些參數
5、getopts檢測到非法參數就會停止,比如上例中遇到34就會終止,并不會去檢測-m了,也就是說只要前一個參數是合法的(包含在option_string中的),就會繼續檢測下一個參數。
另外: unset OPTIND? 可以解決shell腳本的函數中使用getopts
總結
以上是生活随笔為你收集整理的shell 命令行实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下搭建mrbs会议室预定管理系
- 下一篇: linux shell中的命令自动补全(