如何获取以'+'开头的选项值?类bash Shell的getopt_long适配方案
用getopt_long()处理类bash Shell中
+开头的选项 最近我在给自研的类bash Shell写选项解析器,遇到个头疼的问题:为了兼容bash的行为,得处理以+开头的选项,比如./42sh +O autocd [...]——根据bash手册,这类选项是传给内置命令shopt用来配置Shell参数的。但getopt_long()函数只认-或--开头的选项(单独的-在bash里是标准输入的别名,--则是选项结束的标记),一开始我都在纠结,是不是必须完全自己写解析逻辑来处理这种+开头的选项?
后来看了@jxh的回复,又翻了man 3 getopt手册,才发现getopt和getopt_long会自动重排argv参数数组,把它们判定为无效的选项移到数组末尾。这下就有办法了!我在常规的标准选项解析代码之后,加了一段处理剩余参数的逻辑,还修复了一开始循环里每次调用strdup()导致的内存泄漏问题,最终代码如下:
for(; optind < argc; ++optind) { const char *argv_copy = strdup(argv[optind]); if (argv_copy[0] == '+' && argv_copy[1] == 'O') { /* 发现一个shopt配置选项! */ 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; }
这段代码的思路就是遍历getopt_long()解析后剩下的参数,检查是否是+O开头的选项,如果是就调用对应的shopt处理函数,同时跳过后续的参数值,最后记得释放strdup分配的内存避免泄漏。
内容的提问来源于stack exchange,提问作者François de Mareschal
相关产品推荐
相关产品推荐

