【问题标题】:How to get the value of an option which begins with '+' character?如何获取以“+”字符开头的选项的值?
【发布时间】:2018-03-23 23:07:57
【问题描述】:

我正在为我开发的类似 bash 的 shell 编写一个选项解析器。

不过,为了与 bash 选项兼容,我必须阅读一些以“+”开头的选项,如下所示:

./42sh +O autocd [...]

(手册页说这些选项将传递给设置设置值的内置shopt)。

问题是getopt_long() 函数只返回以--- 开头的选项,如果它们不是单独的。如果是,则 bash 将它们分别视为标准输入的别名和选项结束标记。

如何使用 getopt_long() 获得此类选项?我必须自己解析这些选项吗?

编辑:根据@jxh 响应和man 3 getopt 页面,我发现getoptgetopt_long 排列**argv 参数数组以移动所有似乎不是有效选项的参数 - 从他们的观点 - 最后。因此,我在获得 normal 选项的常用代码之后编写了以下代码(非常感谢所有建议和评论):

EDIT2 : 修复了由于 strdup() 在循环的每次迭代中导致的内存泄漏。

for(; optind < argc; ++optind)
{
    const char *argv_copy = strdup(argv[optind]);
    if (argv_copy[0] == '+' && argv_copy[1] == 'O')
    {
        /* A deactivation parameter have been just found ! */
        if (handle_shopt_options(shell_options,
                                 argv[optind + 1],
                                 DISABLE) == EXIT_FAILURE)
        {
            usage(argv[optind]);
            free_shell_options(shell_options);
            shell_options = NULL;
        }
            ++optind;
    }
    free(argv_copy);
    argv_copy = NULL;
}

一些解释:

  • optindargv 索引,它告诉我们哪个参数在下一次传递中被解析。由于我们解析了所有 getopt() 观点的有效参数,并且由于 getopt() 在最后移动了所有非选项,我们将解析所有剩余的参数,包括我们感兴趣的参数。
  • argv[argc] == NULL :这个技巧是用来知道参数列表的末尾在哪里,所以在optind == argc时解析参数是没有用的。
  • 我不习惯直接使用当前的 argv 值,所以我更喜欢将它复制到一个新字符串中,但我可能错了,需要验证。

一些备注:

  • 仅当定义了 _GNU_SOURCE 宏时,getopt_long() 才可用。
  • strdup() 仅在宏 _XOPEN_SOURCE &gt;= 500 或宏 _POSIX_C_SOURCE &gt;= 200809L 时可用。

【问题讨论】:

    标签: c bash c99 getopt getopt-long


    【解决方案1】:

    正如您在研究中指出的那样,您不能使用getopt_long 来解析以+ 开头的选项。

    作为一种解决方法,您可以自己扫描argv[],然后创建一个新的参数向量,在您认为是原始argv[] 中的+ 样式选项的每个参数前面替换--plus-。这个新数组应该可以被getopt_long解析。

    【讨论】:

    • 当代码完成扫描argv[]的工作时,应该已经获取了所有参数,并且每个找到的参数都可以立即处理到程序中的适当标志中。所以不需要创建一个新数组
    • @user3629249 这个想法是编写少量代码来执行简单的替换,然后利用getopt 进行实际的参数处理。
    • 你能告诉我如何创建一个新的参数向量吗?我们不能只添加到相应的argv[i],可以吗?我的意思是,它会扰乱阵列?
    • @J...S:是的,不要修改argv[] 中的字符串。相反,为您计划更改的字符串分配新字符串。如果您希望在原始的 argv[] 上覆盖旧条目,则可以用新条目覆盖,但改为创建 new_argv[] 可能更清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 2023-03-26
    • 2012-07-05
    • 2020-06-25
    • 2011-05-29
    • 1970-01-01
    相关资源
    最近更新 更多