Linux下命令行解析

本文将讲解linux下与命令行解析有关的三个函数:getopt();getopt_long();getopt_long_only();

1.命令行参数

GNU/Linux的命令行控制量有两种:选项和参数。

其中选项有两种类型:短选项和长选项,前者以 '-' 作为前导符,后接一个字符;后者以 '--' 作为前导符,后接一个字符串。选项后面可以接参数(该参数形式和选项相关),也可以不接参数。

例如有一个命令

$ myprog -a vv --add -b --file a.txt b.txt - -- -e c.txt

在GNU/Linux系统,对这种情况的一种合理解释是:
a是短选项,带一个参数vv;
add是长选项,无参数;
b是短选项,无参数;
file是长选项,带一个参数a.txt;
b.txt是参数;
-是参数,通常表示标准输入,stdin;
--是一个指示符,表明停止扫描参数,其后所有部分都是参数,而不是选项;
-e是参数;
c.txt是参数

名字

  getopt, getopt_long, getopt_long_only, optarg, optind, opterr, optopt - 解析命令行选项

摘要

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;

#include <getopt.h>

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);

glibc特性测试宏(见feature_test_macros(7)):

getopt(): _POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE
getopt_long(), getopt_long_only(): _GNU_SOURCE

说明:

  getopt()函数用于解析命令行参数。其参数argc和argv为调用程序时传给main()函数的参数个数和列表.以'-'开头的argv元素被称为一个选项元素。该元素字符(除去开头的'-')叫选项字符。如果重复调用getopt(),它会成功返回每个选项元素的选项字符。

  变量optind是argv中下一个将被处理的元素的索引。系统将其值初始化为1。调用者可以将其值重设为1,以重新扫描原argv表或新的argv表。

  如果getopt()找到一个选项字符串,它返回该字符串,更新extern变量optind和一个static变量nextchar以至下一次调用getopt()能够扫描下一个选项字符串或argv元素。

  如果不再有选项字符串(解析完成),getopt()返回-1。而optind成为第一个非选项argv元素的索引。

  optstring是一个字符串,它包含了合法的选项字符串。如果某字符后接了一个冒号,表示该选项需要一个参数,则getopt()放置一个指针指向同一argv元素的随后文本,或optarg中的下一个argv元素。两个冒号表示该选项代一个可选参数;如果当前argv元素中(选项之后)有文本(例如选项名相同的字符如"-oarg"),则该文本将在optarg中返回,否则optarg将被置为0。这是一个GNU扩展:如果optstring包含之后带分号的W,则-Wfoo被看成长选项--foo。(-W选项被POSIX.2实现扩展保留。)该行为是一个GNU扩展,glibc2之前的库不可用此行为。

  默认地,getopt()在扫描argv时会对其排序,以至最后非选项都在argv表末端。另外两个模式也被实现:如果optstring的第一个字符为+或环境变量POSIXLY_CORRECT设置的字符,则一旦遇到一个非选项argv元素就马上停止选项处理。如果第一个字符为'-',则将每个非选项argv元素作为选项 1的参数处理。(用于期望选项和其他argv元素以任意顺序出现的程序和在意这两者的顺序的程序。)不论何种扫描模式,特殊参数"--"强制结束选项扫描。
  如果getopt()无法识别某个选项字符,它向strerr(标准出错)打印一条错误信息,将该字符保存至optopt,且返回'?'。调用程序可以将opterr设为0以阻止输出错误信息。

  如果getopt()在argv中找到一个未包括在optstring中的选项字符,或发现一个选项缺少参数,它返回'?'且将extern变量optopt设置为该实际选项字符。若optstring的第一个字符(接着任何上述可选'+'或'-')是一个冒号(':'),那么选项缺少参数时getopt()返回':'而不是'?'。若发现错误,且optstring的第一个字母不是冒号且extern变量opterr非零(默认如此),getopt()才打印一条错误信息。

getopt_long()和getopt_long_only()

  getopt_long()函数的工作方式类似与getopt(),但它还能够接受以两个破折号(--)开头的长选项。(如果程序只接受长选项,那么optstring应该设为空字符串(""),而不是NULL。)长选项名应该被缩写,如果该缩写唯一或和某些已定义选项精确匹配。长选项可能带一个参数,以--arg=param或--arg param的形式。

  longopts是一个指针,它指向struct option数组的第一个元素,该结构定义于<getopt.h>中

struct option {
    const char *name;
    int has_arg;
    int *flag;
    int val;
};

各个成员的意义如下:

name    长选项的名称

has_arg   取值为no_argument(或0)时表示该选项不带参数;

       为required_argument(或1)时表示该选项要带参数;

       为optional_argument(或2)时表示该选项带可选参数;

flag      指明长选项如何返回。如果flag为NULL,getopt_long()返回val。(例如,调用程序可能

       将val设置得和短选项字符相同。)否则,getopt_long()返回0,且如果发现选项,flag指

       向一个设为val的变量,但如果未发现选项,则不改变flag。

val      为返回值,或载入flag指向的变量。

  数组的最后一个元素的所有成员必须都置为0;

  如果longindex不为NULL,它指向一个变量,该变量被设为长选项在longopts的索引。

  getopt_long_only()类似于getopt_long(),但'-'和'--'都表示长选项。如果以一个'-'开头的选项没有匹配的长选项,但有匹配的短选项,则他被解析为一个短选项。

原文地址:https://www.cnblogs.com/zechen11/p/2278612.html