經過一個例子來理解什麼是Linux命令參數。以Linux中經常使用的刪除命令「rm」爲例,輸入「rm --help」能夠看到以下信息,其中紅色框內的就是命令參數。常用Linux對命令參數應該是很是熟悉的。例如咱們常用的刪除命令「rm -rf filename」。若是咱們本身開發Linux命令,用代碼來解析命令參數呢?Linux的標準庫函數爲咱們提供了相關的方法。數組
getopt()函數只能處理短選項(如上圖中的「-f」,「-i」等單個字符的選項稱爲短選項,「--verbose」,「--help」等選項稱爲長選項)。getopt_long()函數既能處理短選項也能處理長選項。getopt_only()函數與getopt_long()函數相同。app
#include <unistd.h> #include <getopt.h> extern char *optarg; extern int optind, opterr, optopt; int getopt(int argc, char * const argv[], const char *optstring); int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longidx); int getopt_long_only(int argc, char * const argv[], const char *optstring, const sturuct option *longopts, int longidx);
關於幾個全局變量的說明。函數
1. optarg:表示當前選項對應的參數值,若是沒有參數,值爲NULL。ui
2. optind:表示的是下一個將被處理到的參數在argv中的下標值。spa
3. opterr:若是opterr = 0,在getopt(),getopt_long()和getopt_long_only()函數遇到錯誤將不會輸出錯誤信息到標準輸出流。若是opterr != 0,向 屏幕輸出錯誤。code
4. optopt:表示沒有被未標識的選項。blog
#include <unistd.h> int getopt(int argc, char * const argv[], const char *optstring);
1. argc, argv:這兩個參數就是main()函數中的參數。
2. optstring:由短選項參數組成的字符串。短選項字符串形式能夠是「abc:d::e」,說明以下。
(1). 只有一個字符,不帶冒號:表示選項,不帶參數,如「-a」。
(2). 一個字符,後面帶一個冒號:表示該選項必須帶參數,不帶參數就會出錯,如「-c argument」。
(3). 一個字符,後面帶兩個冒號:表示該選項帶或者不帶參數均可以,如「-d [argument]」。開發
3. getopt()返回值:正確返回短選項字符,錯誤返回-1.字符串
#include <stdio.h> #include <unistd.h> #include <stdarg.h> #include <string.h> #include <stdlib.h> #define BUFSZ 4096 static void log_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt); char buf[BUFSZ]; vsnprintf(buf, BUFSZ - 1, fmt, ap); fputs(buf, stdout); fflush(stdout); va_end(ap); } int main(int argc, char *argv[]) { if (argc == 1) { log_msg("usage: command -t argument."); exit(0); } int c; while ((c = getopt(argc, argv, "ab:c::")) != -1) { switch (c) { case 'a': log_msg("-a option is received."); break; case 'b': log_msg("-b option is received. its argument = %s.", argv[optind - 1]); break; case 'c': log_msg("-b option is received. its argument = %s.", argv[optind]); break; default: break; } } exit(0); }
#include <unistd.h> #include <getopt.h> int getopt_long(int argc, char * const argv[], const char *optstring, const struct option long_opts, int longidx);
1. argc,argv:main()函數的入參。get
2. optstring:短選項字符串,與getopt()函數中的optstring參數相同。
3. long_opts:長選項參數結構體數組。
4. longidx:長選項結構體數組下標。
5. 返回值:參考struct option結構體說明。
struct option { const char *name; int has_arg; int *flag; int val; }; name:表示長選項的名稱。 has_arg:表示長選項後面是否帶有參數。取值以下。 no_argument(或者0):選項後面不帶參數,輸入格式爲「--option」,如「--help」。 required_argument(或者1):選項後面必須帶參數,輸入格式爲「--option arg」或者「--option=arg」,如「--file FILE」或者「--file=FILE」。 optional_argument(或者2):選項後面可選擇性的帶參數,若是帶參數,輸入格式爲「--option=arg」。 flag:該值能夠爲NULL或者非NULL。 NULL:當選中該長選項時,getopt_long()的返回值爲val。 非NULL:當選中該長選項時,getopt_long()的返回值爲0,並將flag指向val。 val:當flag爲NULL時,指定getopt_long()函數的返回值。當flag非NULL時,flag指向val。
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> #include <getopt.h> #include <string.h> #define BUFSZ 4096 static void log_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt); char buf[BUFSZ]; vsnprintf(buf, BUFSZ - 1, fmt, ap); strcat(buf, "\n"); fputs(buf, stdout); fflush(stdout); va_end(ap); } int main(int argc, char *argv[]) { struct option long_opts[] = { { "add", required_argument, NULL, 1 }, { "append", no_argument, NULL, 2 }, { "create", optional_argument, 3 } }; int c; int optidx = 0; while ((c = getopt_long(argc, argv, NULL, long_opts, &optidx)) != -1) { switch (c) { case 1: log_msg("--add option with argument %s", optarg); break; case 2: log_msg("--append option with no argument."); break; case 3: if (optarg) { log_msg("--create option with argument %s", optarg); } else { log_msg("--create option with no argument."); } break; default: break; } } exit(0); }