经过一个例子来理解什么是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); }