GETOPT - Linux手册页

时间:2019-08-20 18:00:58  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

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()函数的参数计数和数组。以aq-aq开头(且不完全是"-"或"-")的argv元素是选项元素。该元素的字符(除了初始aq-aq之外)是选项字符。如果重复调用getopt(),它将依次从每个选项元素中返回每个选项字符。

变量optind是argv中要处理的下一个元素的索引。系统将此值初始化为1。调用者可以将其重置为1,以重新开始扫描相同的argv,或者在扫描新的自变量向量时重新启动。

如果getopt()找到另一个选项字符,它将返回该字符,更新外部变量optind和静态变量nextchar,以便对getopt()的下一次调用可以使用以下选项字符或argv元素恢复扫描。

如果没有其他选项字符,则getopt()返回-1。然后optind是第一个argv元素的argv中的索引,该索引不是选项。

optstring是包含合法选项字符的字符串。如果此类字符后接冒号,则该选项需要一个参数,因此getopt()将指针指向位于同一argv-element中的后续文本或optarg中的下一argv-element的文本。两个冒号表示一个选项带有一个可选的arg;如果当前argv元素中有文本(即与选项名称本身相同的词,例如" -oarg"),则将其以optarg返回,否则optarg设置为零。这是一个GNU扩展。如果optstring包含W后跟一个分号,则-W foo被视为long选项--foo。 (-W选项由POSIX.2保留用于实现扩展。)此行为是GNU扩展,不适用于glibc 2之前的库。

默认情况下,getopt()会在扫描时置换argv的内容,以便最终所有非选项都位于末尾。还实现了其他两种模式。如果optstring的第一个字符是aq + aq或设置了环境变量POSIXLY_CORRECT,则一旦遇到非选项参数,选项处理就会停止。如果optstring的第一个字符是aq-aq,则每个非选项argv-element的处理方式都将其视为字符代码为1的选项的自变量。特殊参数"-"强制结束选项扫描,而与扫描模式无关。

在处理选项列表时,getopt()可以检测两种错误:(1)在optstring中未指定的选项字符,以及(2)缺少选项参数(即,命令行末尾的选项中没有预期参数)。此类错误的处理和报告如下:

*
默认情况下,getopt()在标准错误上显示一条错误消息,将错误的选项字符放在optopt中,并返回aq?aq作为函数结果。
*
如果调用者已将全局变量opterr设置为零,则getopt()不会显示错误消息。调用方可以通过测试函数返回值是否为aq?aq来确定存在错误。 (默认情况下,opterr具有非零值。)
*
如果optstring的第一个字符(在上述任意可选的aq + aq或aq-aq之后)是冒号(aq:aq),则getopt()同样不会显示错误消息。另外,它返回aq:aq而不是aq?aq来指示缺少的选项参数。这使调用者可以区分两种不同类型的错误。

getopt_long() and getopt_long_only()

getopt_long()函数的工作方式与getopt()相同,不同之处在于它还接受以两个破折号开头的长选项。 (如果程序仅接受长选项,则应将optstring指定为空字符串(""),而不是NULL。)如果缩写是唯一的或与某些已定义选项完全匹配,则可以缩写长选项名。长选项可以采用--arg = param或--arg param形式的参数。

longopts是指向以以下方式声明的struct选项数组的第一个元素的指针:

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设置为等效的short选项字符。)否则,getopt_long()返回0,并且如果找到该选项,则标志指向设置为val的变量,但是如果该选项为未找到。
val
是要返回的值,或者是加载到flag指向的变量中的值。

数组的最后一个元素必须用零填充。

如果longindex不为NULL,则指向一个变量,该变量设置为long选项相对于longopts的索引。

getopt_long_only()类似于getopt_long(),但是aq-aq和"-"可以表示一个长选项。如果以aq-aq开头的选项(不是"-")与长选项不匹配,但与短选项匹配,则将其解析为短选项。

返回值

如果成功找到选项,则getopt()返回选项字符。如果已解析所有命令行选项,则getopt()返回-1。如果getopt()遇到不在optstring中的选项字符,则返回aq?aq。如果getopt()遇到带有缺少参数的选项,则返回值取决于optstring中的第一个字符:如果它是aq:aq,则返回aq:aq;否则返回aq:aq。否则返回aq?aq。

当识别到短选项时,getopt_long()和getopt_long_only()也返回选项字符。对于长选项,如果标志为NULL,则返回val,否则返回0。 Error和-1返回与getopt()相同,加上aq?aq表示歧义匹配或无关参数。

环境

POSIXLY_CORRECT
如果设置了此选项,则一旦遇到非选项参数,选项处理就会停止。
_<PID>_GNU_nonoption_argv_flags_
bash(1)2.0使用此变量与glibc通讯,哪些参数是通配符扩展的结果,因此不应将其视为选项。此行为在bash(1)2.01版中已删除,但支持仍在glibc中。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
getopt(),getopt_long(),getopt_long_only()Thread safetyMT-Unsafe race:getopt env

遵循规范

getopt():
如果设置了环境变量POSIXLY_CORRECT,则POSIX.1-2001,POSIX.1-2008和POSIX.2。否则,argv的元素并不是真正的const,因为这些函数会置换它们。但是,原型中使用了const以便与其他系统兼容。
在optstring中使用aq + aq和aq-aq是GNU扩展。
在某些较旧的实现中,getopt()在中声明。 SUSv1允许声明出现在或中。 POSIX.1-1996将该用途标记为LEGACY。 POSIX.1-2001不需要声明出现在中。
getopt_long() and getopt_long_only():
这些功能是GNU扩展。

备注

一个程序必须扫描多个参数向量,或者不止一次扫描相同的向量,并且想要在optstring的开头使用gq扩展名,例如aq + aq和aq-aq,或者在两次扫描之间更改POSIXLY_CORRECT的值通过将optind重置为0而不是传统值1来重新初始化getopt()(重置为0会强制调用内部初始化例程,该例程会重新检查POSIXLY_CORRECT并检查optstring中的GNU扩展。)

示例

getopt()

以下简单示例程序使用getopt()处理两个程序选项:-n,没有关联值; -t val,它需要一个关联的值。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    int flags, opt;
    int nsecs, tfnd;

    nsecs = 0;
    tfnd = 0;
    flags = 0;
    while ((opt = getopt(argc, argv, "nt:")) != -1) {
        switch (opt) {
        case aqnaq:
            flags = 1;
            break;
        case aqtaq:
            nsecs = atoi(optarg);
            tfnd = 1;
            break;
        default: /* aq?aq */
            fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\n",
            flags, tfnd, nsecs, optind);

    if (optind >= argc) {
        fprintf(stderr, "Expected argument after options\n");
        exit(EXIT_FAILURE);
    }

    printf("name argument = %s\n", argv[optind]);

    /* Other code omitted */

    exit(EXIT_SUCCESS);
}

getopt_long()

以下示例程序说明了getopt_long()及其大多数功能的用法。

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>

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, aqcaq},
            {"file",    required_argument, 0,  0 },
            {0,         0,                 0,  0 }
        };

        c = getopt_long(argc, argv, "abc:d:012",
                 long_options, &option_index);
        if (c == -1)
            break;

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

        case aq0aq:
        case aq1aq:
        case aq2aq:
            if (digit_optind != 0 && digit_optind != this_option_optind)
              printf("digits occur in two different argv-elements.\n");
            digit_optind = this_option_optind;
            printf("option %c\n", c);
            break;

        case aqaaq:
            printf("option a\n");
            break;

        case aqbaq:
            printf("option b\n");
            break;

        case aqcaq:
            printf("option c with value aq%saq\n", optarg);
            break;

        case aqdaq:
            printf("option d with value aq%saq\n", optarg);
            break;

        case aq?aq:
            break;

        default:
            printf("?? getopt returned character code 0%o ??\n", c);
        }
    }

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

    exit(EXIT_SUCCESS);
}

另外参见

getopt(1),getsubopt(3)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/