如何从 C 函数创建 shell 命令

2024-05-09

想知道如何获取一组 C 函数并将它们转换为 shell/bash 命令。

假设我有一组简单的 C 函数

int
fn1() {
  // some C code for function 1.
}

int
fn2() {
  // some C code for function 2.
}

int
fn3() {
  // some C code for function 3.
}

然后我想以某种方式创建 CLI 命令,以便我可以从终端使用它们。

$ fn1 <param> <param> ...
$ fn2 ...
$ fn3 ...

不确定这样做的过程是什么。如果我需要以某种方式重写 shell 脚本中的所有函数接口,然后以某种方式调用 C 函数,有点像这样(bash 脚本):

fn1() {
  callc mylib/fn1 $1 $2
}

fn2() {
  ...
}

...

或者,如果我可以通过将每个 C 函数分成单独的文件来自动将它们转换为 shell 脚本fn1.c, fn2.c等等,并以某种方式将它们加载到外壳中source ~/.bash_profile类型的事物。

任何帮助将不胜感激,谢谢。


或者也许采用老式方法:编写 C 代码来检查它是如何被调用的(原始命令行参数中的第 0 个参数)并根据该名称调用正确的 C 函数。需要将此类 C 程序编译为单个可执行文件,然后创建指向基本应用程序的符号链接,其中符号链接是感兴趣的函数的名称。除了将此处的工件(可执行文件和符号链接)安装到 $PATH 中的目录中之外,不需要 shell 代码。

例子。如果以下代码的名称为 toybox.c,并且 ~/bin 存在且位于用户的 $PATH 中,请使用类似以下内容的代码:

$ cc -o ~/bin/toybox toybox.c
$ ln -s toybox ~/bin/fn1
$ ln -s toybox ~/bin/fn2
$ ln -s toybox ~/bin/fn3

简单的测试 - 仅表明脚手架已就位。

$ fn1
fn1 invoked - no arguments.
$ fn3 1 2 'a b c'
fn3 invoked - arguments:
  1 - '1'
  2 - '2'
  3 - 'a b c'

toybox.c 的源代码可能如下所示:

#include <string.h>
#include <libgen.h>
#include <stdio.h>

struct name2func {
    const char *name;
    int (*func)(int ac, char *const av[]);
};

void
fn_debug(const char *fn, int ac, char *const av[])
{
    int n;

    printf("%s invoked - ", fn);

    if (ac <= 0) {
        printf("no arguments.\n");
    } else {
        printf("arguments:\n");
        for (n = 0; n < ac; n++) {
            printf("  %d - '%s'\n", n + 1, av[n]);
        }
    }
}

int
fn1(int ac, char *const av[])
{
    fn_debug("fn1", ac, av);
    /* some C code for function 1. */
    return 0;
}

int
fn2(int ac, char *const av[])
{
    fn_debug("fn2", ac, av);
    /* some C code for function 2. */
    return 0;
}

int
fn3(int ac, char *const av[])
{
    fn_debug("fn3", ac, av);
    /* some C code for function 3. */
    return 0;
}

/*
 * Establish a crude symbol table after function definitions: size of
 * the name2func array (i.e., its number of elements) is available via the
 * sizeof builtin.
 */

struct name2func n2f[] = {
  { "fn1", fn1 },
  { "fn2", fn2 },
  { "fn3", fn3 }
};

int
dispatch(const char *func_name, int ac, char *const av[])
{
    size_t n;

    /* linear search ok for small # of funcs */

    for (n = 0; n < sizeof n2f / sizeof n2f[0]; n++) {
        if (strcmp(func_name, n2f[n].name) == 0) {
            return (*n2f[n].func)(ac, av);
        }
    }

    fprintf(stderr, "%s: unsupported\n", func_name);
    return 1;
}

int
main(int argc, char *const argv[])
{
    /*
     * using POSIX basename(3) to create, say, "fn1" from
     * a full-path invocation like "/my/odd/dir/fn1".
     */
    char *fnbase = basename(argv[0]);

    if (fnbase == 0) {
        perror("basename");
        return 1;
    }

    return dispatch(fnbase, argc - 1, argv + 1);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 C 函数创建 shell 命令 的相关文章

  • 数据结构的优化存储以实现快速查找和持久化

    Scenario 我有以下方法 public void AddItemSecurity int itemId int userIds public int GetValidItemIds int userId 最初我正在考虑表单上的存储 i
  • 是否可以通过引用以基类作为参数的函数来传递派生类

    假设我们有一个抽象基类IBase使用纯虚方法 接口 然后我们推导出CFoo CFoo2来自基类 我们有一个知道如何使用 IBase 的函数 Foo IBase input 这些情况下通常的场景是这样的 IBase ptr static ca
  • ASP.NET 数据集 getdataBy 无法启用约束。一行或多行包含违反非空、唯一或外键约束的值

    你好 我有一个非常简单的网络表单 我在此表单上有一个按钮和一个网格视图 以及一个包含链接表 bill docket docket bill 等的数据集 在按钮上单击我使用以下代码 protected void button click ob
  • 通过 EUSART PIC18F45K80 打印消息

    我正在尝试向 Docklight 发送串行消息 但始终收到空值 我正在使用带有 XC8 MPLAB X 的 PIC18F45K80 我的代码中的所有内容似乎都是正确的 但我想我错了 我该如何修复它 include
  • 我可以将特定警告视为错误吗?

    以下是我有时在学生代码中看到的模式的简化版本 bool foobar int a int b if a lt b return true 当然 真正的代码要复杂得多 Visual Studio 报告警告 C4715 并非所有控制路径都会返回
  • memccpy 返回比 src 起始地址更低的内存地址

    我有一个学校项目 我必须重新编码memccpy 功能 我使用 2 个程序来检查我的代码是否正常工作 第一个是只有一个主程序的小程序 第二个程序是另一个学生开发的 可以找到here https github com yyang42 mouli
  • Math.Sin、Math.Cos 和 Math.Tan 精度以及正确显示它们的方法

    我正在用 C 编写一个计算器 textBoxResult是一个文本框 我在其中显示数字 recount是以度为单位获取角度并以弧度为单位返回的函数 我的角度是从texBoxInput public double recount int nu
  • 本地主机和 request.Url.Authority

    我的应用程序通过 URL 中的公司标识符分隔用户 company1 app com company2 app com 我正在本地 PC 上进行测试 请求如下 company1 localhost com 但是 我的 request Url
  • C++ 虚拟关键字与重写函数

    我正在学习c 并且正在学习virtual关键字 我在互联网上搜索试图理解它但无济于事 我进入编辑器并做了以下实验 期望它打印两次基本消息 因为我的印象是需要 virtual 关键字来覆盖函数 然而 它打印出了两条不同的消息 有人可以向我解释
  • Ajax 函数在重定向后不保存滚动位置

    正如标题所述 我编写了一个 ajax 函数 该函数应该滚动到用户在重定向之前所在的位置 我写了一个alert对于测试场景 它确实触发了 但滚动不断回到顶部 我在这里做错了什么 JavaScript ajax type GET url Adm
  • 如何将对 System.Data.DataSetExtensions 的引用添加到网站 ascx.cs 文件?

    我们正在处理一个网站项目并尝试参考System Data DataSetExtensions 使用 Web 应用程序会更好 不过 技术主管有她的理由 这是我们尝试过的 找到装配路径 打开 Visual Studio 命令提示符并运行sn e
  • 当 C 中没有足够的内存用于静态分配时会发生什么?

    当您动态分配内存时 例如malloc 1024 sizeof char 结果指针设置为NULL如果没有足够的可用内存来满足请求 当没有足够的内存来满足静态分配时会发生什么 例如char c 1024 char c 1024 不一定是静态分配
  • 验证域用户凭据

    我需要一种方法来验证 Windows 上本机 C 的用户 密码对 输入的是用户名和密码 用户可以是 DOMAIN user 格式 基本上我需要编写一个函数 如果用户 密码是有效的本地帐户 则返回 true 第1部分 如果用户 密码在给定的域
  • 来自资源中 ImageSource 的 System.Drawing.Image

    我的问题与这个非常相似 wpf图像资源以及运行时在wpf控件中更改图像 https stackoverflow com questions 940592 wpf image resources and changing image in w
  • 不兼容的指针到字符转换

    我正在编写一个程序 将卡片值写入 52 个点字符的多维数组中 该程序是一个测试数组 稍后我将其作为函数写入主程序中 在程序中 我通过以下方式初始化 for 循环计数0通过51 我用一个switch语句调制13将卡牌值分配给数组点 但是 我收
  • C++ 项目编译为静态库,编译为动态库失败(链接器错误)。为什么?

    我有一个 VS2008 本机 C 项目 我希望将其编译为 DLL 它仅引用一个外部库 log4cplus lib 并使用其功能 当然也使用 log4cplus 的 h 文件 当我尝试将我的项目编译为静态库时 它成功了 当我尝试作为 DLL
  • WPF DataGrid 选定项

    我有一个 DataGrid 用户可以通过在最后一行输入数据来添加项目 我还有一个按钮可以删除当前选定的项目 但是 当选择最后一行 空 用于添加新项目 时 最后选定的项目将保留在 SelectedItem 中 因此 如果我打开窗口 选择最后一
  • 如何将命令输出作为多个参数传递给另一个命令

    我想将命令的每个输出作为多个参数传递给第二个命令 例如 grep pattern input returns file1 file2 file3 我想复制这些输出 例如 cp file1 file1 bac cp file2 file2 b
  • Python 子进程:无法转义引号

    我知道以前曾问过类似的问题 但它们似乎都是通过重新设计参数的传递方式 即使用列表等 来解决的 但是 我这里有一个问题 因为我没有这个选项 有一个特定的命令行程序 我使用的是 Bash shell 我必须向其传递带引号的字符串 它不能不被引用
  • 清理 TPL 中的 CallContext

    根据我使用的是基于 async await 的代码还是基于 TPL 的代码 我在逻辑清理方面得到了两种不同的行为CallContext 我可以设置和清除逻辑CallContext如果我使用以下异步 等待代码 正如我所期望的 class Pr

随机推荐