You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:15:14