一、Linux傳入參數處理shell
在介紹使用getopt函數處理應用程序傳入參數前,先來看一下Linux環境下編寫的應用程序是如何處理傳入的參數的數組
Linux環境編寫應用程序時,main函數通常會有兩個參數,用於描述執行應用程序時傳入的參數,書寫形式以下:函數
int main(int argc, char *argv[])
在shell中啓動這個應用程序,shell接受用戶輸入命令行,將命令行分解成單詞,而後把這些單詞放入到一個數組,操做系統將這個存放單詞數組的長度和數組做爲參數傳遞給了main函數。所以,實際狀況下,argv[0]指向的必定是運行當前應用程序的全路徑名稱,argv[1]~argv[argc-1]指向的纔是傳入參數,實際傳入參數的個數爲argc-1spa
例若有一個名爲hello_world應用程序,在shell中按照 "./hello_world 3" 執行該程序,此時,argc = 2,argv[0]指向的是 "./hello_world" 字符串存放地址,argv[1]指向的纔是傳入參數 "3" 字符串存放地址
操作系統
顯然,咱們能夠在main函數內本身編寫程序,經過解析argc,argv參數來獲取執行應用程序所傳入的參數。但對於Linux這種普遍使用的操做系統,它已經在庫函數中爲用戶提供了用於命令行參數解析的函數,咱們直接調用這些函數,即可輕鬆的解析各類命令行參數模式命令行
這裏所講的getopt函數,就是標準庫中實現的一個用於解析命令行參數的函數,它支持須要關聯值和不須要關聯值的選項,並且簡單易用指針
(所謂的須要關聯值的選項,以gcc編譯器爲例子,gcc的-o選項表示輸出可執行程序名稱,這個後面就須要跟一個名稱才能正常使用,後面一個參數就是-o命令的關聯值;所謂的不須要關聯值,以ls命令爲例子, ls的-l命令表示列出當前目錄全部文件,這個後面不須要跟一些其餘信息,這種被稱做不須要關聯值的選項)code
二、getopt函數的原型blog
getopt函數有三個參數,函數的原型以下:索引
int getopt(int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt;
getopt函數本質上其實就是對main函數傳入的argc和argv參數進行處理,它將傳遞給程序的main函數的argc和argv做爲參數,同時接受一個選項指定字符串optstring。optstring字符串告訴getopt哪些選項可用,以及它們是否有關聯值。
optstring是一個字符串列表,每一個字符表明一個單字符選項。若是一個字符後面緊跟一個冒號(:),則表示一個該選項有一個關聯值做爲下一個參數。
例如:getopt(argc, argv, "if:l")
它容許-i、-f、-l做爲參數,其中-f選項後要緊跟一個參數,也就是它的關聯值。這裏參數的傳遞能夠不按照optstring字符串列表寫入的順序來傳
getopt的返回值是argv數組中的下一個選項字符,循環調用getopt能夠依次獲得argv中每個選項。函數的處理行爲以下:
optind表示下一個待處理參數的索引,getopt利用它來記錄本身的進度,通常狀況下在程序中不多用到
三、函數的使用
編寫一個簡單的例子,來演示getopt函數使用
#include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { int res; while((res = getopt(argc, argv, ":io:l")) != -1) { switch(res) { case 'i': case 'l': printf("option: %c\n", res); break; case 'o': printf("option: %c %s\n", res, optarg); break; case ':': printf("option need a value\n"); break; case '?': printf("unknown option: %c\n", optopt); break; default: break; } } }
演示程序中的main函數內使用getopt函數對傳入參數進行解析,支持參數有-i、-o、-l,其中-o參數後要有一個關聯值。這裏optstring參數的第一個字符設置成冒號,是用來分辨輸入-o選項,但沒傳入關聯值狀況,這種狀況(:)被返回
若是傳入-i、-l參數,打印參數信息
若是傳入-o參數,打印參數信息和關聯值信息
若是傳入-o參數,並沒傳入關聯值,打印出提示信息
若是傳入無效參數時,打印出不識別提示信息
四、小結
調用getopt函數能夠方便的處理咱們程序中傳入的不一樣參數,它按照咱們指定的方式來解析main函數中傳入的argc和argv參數,並返回選項字符。支持的參數在getopt的optstring參數指定,經過參數後面冒號(:)的有無來表示該參數後面是否須要緊跟關聯值信息。但getopt函數也有本身的侷限性,它僅支持的是單字符參數,若是想接受比單字符選項含義更明確的參數時,就不適用了。不過,若是你有這種需求,能夠去研究下C庫中getopt函數的另外一個加強版本——getopt_long,它接受如下劃線(--)開始的長參數