如何在Argp或Getopt中允许未识别选项并传递给FUSE?
当然可以搞定!不管是用Argp还是Getopt,都有办法让你的程序把未识别的选项无缝传递给FUSE。下面分别给你拆解两种工具的实现方式:
使用Getopt实现
Getopt本身支持抑制错误提示,并且能捕获未识别的选项,我们可以把这些选项收集起来,最后一起传给FUSE的主函数。
核心思路:
- 设置
opterr = 0,关闭Getopt默认的“Unknown option”错误输出 - 循环解析自己的选项,遇到未识别的选项(触发
case '?')时,将其加入FUSE参数列表 - 最后把所有剩余的非选项参数也加入FUSE参数列表,再调用
fuse_main
示例代码:
#include <getopt.h> #include <fuse.h> #include <stdlib.h> int main(int argc, char *argv[]) { int opt; opterr = 0; // 关闭默认错误提示 // 初始化FUSE参数列表,预留足够空间 int fuse_argc = 0; char **fuse_argv = malloc(sizeof(char*) * (argc + 1)); // +1 留空终止符 if (!fuse_argv) { // 处理内存分配失败 return 1; } // 解析自己的专属选项(这里以-a、-b、-c:为例) while ((opt = getopt(argc, argv, "abc:")) != -1) { switch (opt) { case 'a': // 处理你的选项a逻辑 break; case 'b': // 处理你的选项b逻辑 break; case 'c': // 处理选项c的参数optarg break; case '?': // 未识别的选项,加入FUSE参数列表 fuse_argv[fuse_argc++] = argv[optind - 1]; break; } } // 把剩余的非选项参数(比如挂载点)也传给FUSE for (int i = optind; i < argc; i++) { fuse_argv[fuse_argc++] = argv[i]; } // 别忘了把程序名作为FUSE参数的第一个元素(fuse_main要求) fuse_argv[fuse_argc++] = argv[0]; fuse_argv[fuse_argc] = NULL; // 终止符 // 调用FUSE主函数,传递收集到的参数 int result = fuse_main(fuse_argc, fuse_argv, &your_fuse_operations, NULL); free(fuse_argv); return result; }
使用Argp实现
Argp的灵活性更强,它允许你直接标记未识别的选项并保留它们,无需手动收集。
核心思路:
- 在选项解析函数中,遇到
ARGP_KEY_UNKNOWN时返回ARGP_ERR_UNKNOWN,告诉Argp不要处理这个选项 - 调用
argp_parse时加上ARGP_NO_EXIT和ARGP_NO_HELP参数,避免Argp因未识别选项退出或显示帮助 - 解析完成后,Argp会返回剩余的参数列表,直接传给
fuse_main即可
示例代码:
#include <argp.h> #include <fuse.h> // 存储自己的选项配置 struct arguments { int a_flag; int b_flag; char *c_value; }; // 你的专属选项定义 static struct argp_option options[] = { {"enable-a", 'a', 0, 0, "Enable feature A"}, {"enable-b", 'b', 0, 0, "Enable feature B"}, {"set-c", 'c', "VALUE", 0, "Set parameter C to VALUE"}, {0} // 选项列表终止符 }; // Argp选项解析函数 static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct arguments *args = state->input; switch (key) { case 'a': args->a_flag = 1; break; case 'b': args->b_flag = 1; break; case 'c': args->c_value = arg; break; case ARGP_KEY_UNKNOWN: // 未识别的选项,让Argp保留它,不要报错 return ARGP_ERR_UNKNOWN; default: return ARGP_ERR_UNKNOWN; } return 0; } // Argp配置结构体 static struct argp argp = {options, parse_opt, NULL, "Your custom FUSE filesystem"}; int main(int argc, char *argv[]) { struct arguments args = {0}; int fuse_argc; char **fuse_argv; // 解析选项,未识别的会被保留在fuse_argv中 argp_parse(&argp, argc, argv, ARGP_NO_EXIT | ARGP_NO_HELP, &fuse_argc, &args); // 直接把剩余参数传给FUSE主函数 return fuse_main(fuse_argc, fuse_argv, &your_fuse_operations, NULL); }
额外小提示
如果用户习惯用--来分隔你的程序选项和FUSE选项(比如./your-fuse -a -- -d -s /mnt),上面的两种方法也能完美兼容,因为--之后的所有参数都会被当作非选项参数传递给FUSE。
内容的提问来源于stack exchange,提问作者Lapsio
相关产品推荐
相关产品推荐

