我正在为我开发的类似bash的shell编写一个选项解析器。
尽管如此,为了与bash选项兼容,我必须阅读一些以' +'开头的选项,如下所示:
./42sh +O autocd [...]
(手册页说这些选项会传递给内置shopt
,用于设置设置值。
问题是getopt_long()
函数只返回以-
或--
开头的选项,如果它们不是唯一的话。如果是,则bash将它们分别作为标准输入的别名和选项标记的结尾。
我如何使用getopt_long()
获得此类选项?我是否要自己解析这些选项?
编辑:根据@jxh回复和man 3 getopt
页面,我发现getopt
和getopt_long
安排了**argv
参数数组来移动所有参数#&# 39;从最终的角度来看,似乎是有效的选择 - 从他们的角度来看。所以,我在通常的代码之后编写了以下代码,这些代码获得了 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;
}
一些解释:
optind
是argv
索引,它告诉我们在下一次传递中解析将哪个参数。由于我们解析了所有getopt()视点的有效参数,并且由于getopt()在最后移动了所有非选项,我们将解析所有剩余的参数,包括我们感兴趣的参数。argv[argc] == NULL
:这个技巧用于知道参数列表的结尾在哪里,因此在optind == argc
时解析参数是没用的。argv
值,因此我更喜欢将其复制到一个新字符串中,但我可能错了,要进行修改。一些评论:
getopt_long()
宏时,_GNU_SOURCE
才可用。strdup()
仅在宏_XOPEN_SOURCE >= 500
或宏_POSIX_C_SOURCE >= 200809L
时可用。答案 0 :(得分:5)
正如您在研究中所述,您无法使用getopt_long
来解析以+
开头的选项。
作为一种解决方法,您可以自己扫描argv[]
,然后创建一个新的参数向量,在您认为原始版本为--plus-
样式选项的每个参数前面替换+
argv[]
。这个新数组应该由getopt_long
解析。