linux 命令 竖,Linux命令行参数解析

在进行Linux程序开发时,我们最常碰到的一个问题就是:如何设计命令行参数以及如何完成对命令行参数的解析呢?在本文,我们将对这个问题进行详细的阐述和案例分析。

一、库函数详解

当进行命令行参数解析时,主要涉及的库函数包括getopt,getopt_long以及getopt_long_only。其中,主要的参数包括optarg,optind,opterr以及optopt。

现举例说明:$ myprog -a vv --add -b --file a.txt - -- -e c.txt

Linux中的命令行选项有两种类型,包括短选项和长选项。其中,短选项以'-'作为前导符,长选项以'--'作为前导符。

对于以上命令,可以解释如下:1. a是短选项,带一个参数vv;2. add是长选项,无参数;3. b是短选项,无参数;4. file是长选项,带一个参数a.txt;5. -是参数,通常表示标准输入,stdin;6. --是一个指示符,表明停止扫描参数,其后所有部分都是参数,而不是选项;7. -e是参数;8. c.txt是参数。

当执行命令行参数解析时,可以使用一些用于分析命令行参数的函数,它们的原型如下:#include int getopt(int argc, char* const argv[], const char *optstring);extern char *optarg;extern int optind, opterr, optopt;#define _GNU_SOURCE#include int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);int getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

对于用于分析短参数的getopt函数,其原型如下:int getopt(int argc, char* const argv[], const char *optstring);

其中,argc表示命令行参数个数,argv表示命令行参数数组,optstring则表示如何分析命令行参数。

关于optstring,有如下几点说明:如果选项带参数,该选项后接冒号,比如"a:b",则表示a带参数,而b不带参数;

如果选项带可选参数,该选项后接两个冒号,比如"a::b",则表示a可能有参数,也可能不带参数;

如果optstring的起始字符为':',则表示如果指明选项带参数,而实际命令行没有参数时,getopt返回':'而不是'?'(默认情况下返回'?',和无法识别的参数返回一样);

如果optstring的起始字符为'+',则表示一旦遇到一个无选项参数,马上停止扫描,随后的部分当作参数来解释;

如果optstring的起始字符为'-',则表示如果遇到无选项参数,则把它当作选项1(不是字符'1')的参数。

该函数每解析完一个选项,就返回该选项字符。

如果选项带参数,则参数保存在optarg中。如果选项带可选参数,而实际无参数时,optarg为NULL。

当遇到一个不在optstring指明的选项时,返回字符'?'。如果在optstring指明某选项带参数而实际没有参数时,返回字符'?'或者字符':',则根据optstring的起始字符而定。这两种情况选项的实际值被保存在optopt中。

当解析错误时,如果opterr为1则自动打印一条错误消息(默认),否则不打印。

当解析完成时,函数返回-1。

每当解析完一个argv,optind(选项索引)就会递增。如果遇到无选项参数,getopt默认会把该参数调后一位,再解析下一个参数。如果解析完成后还有无选项的参数,则optind指示的是第一个无选项参数在argv中的索引。

对于可以同时分析长选项和短选项的getopt_long函数,其原型如下:int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

相较于getopt函数,它同时能够接收长选项。在接收长选项之前,必须定义一个option结构体数组longopts,用于存储希望解析的长选项信息。

对于option结构体,其定义如下:struct option { const char *name; int has_arg; int *flag; int val;};

对于结构体的每个成员,含义如下:name表示长选项的名称。

has_arg表示该选项是否带参数,包括no_argument,required_argumen以及optional_argument。

flag表示长选项如何返回,如果flag为NULL,则getopt_long返回val。否则返回0,flag指向一个值为val的变量。如果该长选项没有发现,flag保持不变。

val表示长选项的返回值,或需要被加载到flag所指向的变量中。

另外,对于longopts数组,最后一个元素必须被全部填充为0,即{0, 0, 0, 0}。同时,getopt_long函数的最后一个参数longindex在函数返回时指向被搜索到的选项在longopts数组中的下标。longindex可以为NULL,表示不需要返回该值。

getopt_long_only类似于getopt_long,但是它把'-'开头的选项当作长选项来处理。如果该选项与长选项不匹配,而与短选项匹配,则可以作为短选项解析。在短选项找到的时候,getopt_long和getopt_long_only的表现和getopt一样。如果长选项找到了,如果flag为 NULL,返回val,否则返回0。错误情况的处理和getopt一样,只是返回'?'时还可能是别的情况引起的:选项含糊不明确或者无关参数。

二、举例说明

代码如下:#include #include #include int main(int argc, char **argv) { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", required_argument, 0, 0 }, {"append", no_argument, 0, 0 }, {"delete", required_argument, 0, 0 }, {"verbose", no_argument, 0, 0 }, {"create", required_argument, 0, 'c'}, {"file", required_argument, 0, 0 }, {0, 0, 0, 0 } }; c = getopt_long(argc, argv, "a:bc:d:012", long_options, &option_index); if (c == -1) { printf("arguments parse work completed.

"); break; } switch (c) { case 0: printf("option %s", long_options[option_index].name); if (optarg) { printf(" with arg %s", optarg); } printf("

"); break; case '0': case '1': case '2': if (digit_optind != 0 && digit_optind != this_option_optind) { printf("digits occur in two different argv-element.

"); } digit_optind = this_option_optind; printf("option %c

", c); break; case 'a': printf("option a with value '%s'

", optarg); break; case 'b': printf("option b

"); break; case 'c': printf("option c with value '%s'

", optarg); break; case 'd': printf("option d with value '%s'

", optarg); break; case '?': break; default: printf("?? getopt returned character code 0%o ??

", c); } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) { printf("%s ", argv[optind++]); printf("

"); } } exit(EXIT_SUCCESS);}

测试如下:zjl@ubuntu:~/workset/cmdparse$ ./myprog -a vv --add -b --file a.txt --delete doption a with value 'vv'option add with arg -boption file with arg a.txtoption delete with arg darguments parse work completed.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值