如何获取以“+”字符开头的选项的值?
How to get the value of an option which begins with '+' character?
我正在为我开发的 bash-like shell 编写一个选项解析器。
然而,为了与 bash 选项兼容,我必须阅读一些以“+”开头的选项,例如:
./42sh +O autocd [...]
(手册页说这些选项将传递给设置设置值的内置 shopt
)。
问题是 getopt_long()
仅对 returns 以 -
或 --
开头的选项起作用,如果它们不是单独的的话。如果是,bash 将它们分别视为标准输入的别名和选项标记的结尾。
如何使用 getopt_long()
获得此类选项?我必须自己解析这些选项吗?
编辑:根据@jxh 回复和man 3 getopt
页面,我发现getopt
和getopt_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;
}
一些解释:
optind
是 argv
索引,它告诉我们哪个参数 将 在下一次解析。由于我们解析了所有 getopt() 的观点有效参数,并且由于 getopt() 在最后移动了所有非选项,我们将解析所有剩余的参数,包括我们感兴趣的参数。
argv[argc] == NULL
:这个技巧是用来知道参数列表的末尾在哪里,所以当 optind == argc
. 时解析参数是没有用的
- 我不习惯直接用当前的
argv
值来玩,所以我宁愿把它复制到一个新的字符串中,但我可能错了,有待验证。
一些评论:
getopt_long()
只有在定义了 _GNU_SOURCE
宏时才可用。
strdup()
仅在宏 _XOPEN_SOURCE >= 500
或宏 _POSIX_C_SOURCE >= 200809L
. 时可用
正如您在研究中指出的那样,您不能使用 getopt_long
来解析以 +
开头的选项。
作为变通方法,您可以自己扫描 argv[]
,然后创建一个新的参数向量,在您认为是 +
样式选项的每个参数前面替换 --plus-
原来argv[]
。这个新数组应该可以被 getopt_long
.
解析
我正在为我开发的 bash-like shell 编写一个选项解析器。
然而,为了与 bash 选项兼容,我必须阅读一些以“+”开头的选项,例如:
./42sh +O autocd [...]
(手册页说这些选项将传递给设置设置值的内置 shopt
)。
问题是 getopt_long()
仅对 returns 以 -
或 --
开头的选项起作用,如果它们不是单独的的话。如果是,bash 将它们分别视为标准输入的别名和选项标记的结尾。
如何使用 getopt_long()
获得此类选项?我必须自己解析这些选项吗?
编辑:根据@jxh 回复和man 3 getopt
页面,我发现getopt
和getopt_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;
}
一些解释:
optind
是argv
索引,它告诉我们哪个参数 将 在下一次解析。由于我们解析了所有 getopt() 的观点有效参数,并且由于 getopt() 在最后移动了所有非选项,我们将解析所有剩余的参数,包括我们感兴趣的参数。argv[argc] == NULL
:这个技巧是用来知道参数列表的末尾在哪里,所以当optind == argc
. 时解析参数是没有用的
- 我不习惯直接用当前的
argv
值来玩,所以我宁愿把它复制到一个新的字符串中,但我可能错了,有待验证。
一些评论:
getopt_long()
只有在定义了_GNU_SOURCE
宏时才可用。strdup()
仅在宏_XOPEN_SOURCE >= 500
或宏_POSIX_C_SOURCE >= 200809L
. 时可用
正如您在研究中指出的那样,您不能使用 getopt_long
来解析以 +
开头的选项。
作为变通方法,您可以自己扫描 argv[]
,然后创建一个新的参数向量,在您认为是 +
样式选项的每个参数前面替换 --plus-
原来argv[]
。这个新数组应该可以被 getopt_long
.