优秀的编程知识分享平台

网站首页 > 技术文章 正文

我如何用C语言构建简单Shell(三)_c语言编写shell

nanyue 2025-09-04 14:10:19 技术文章 7 ℃

在我的自定义shell项目的这最后一部分中,我们将探索如何在解析后执行用户命令。此时,用户输入已成功分割成参数——现在是采取行动的时候了!


理解execute_command函数

这里的核心函数是:

void execute_command(char **args, int argc, Command *command, int command_count)

将用户输入与预定义命令匹配
执行相应的函数指针
如果没有匹配的命令则打印错误消息

让我们分解它

for (int i = 0; i < command_count; i++)
{
    if (strcmp(args[0], command[i].name) == 0)
    {
        command[i].action(args, argc);
        return;
    }
}
printf("Unknown commnad: %s\n", args[0]);

1. 命令匹配: Shell遍历Command结构体数组,将输入与注册的命令名称进行比较。

2. 函数指针: 如果找到匹配项,通过指针调用相应的函数。

3. 错误反馈: 如果没有找到匹配项,shell通知用户命令未知(故意有个小拼写错误?)。


Command结构

每个命令都是一个看起来像这样的结构体:

typedef struct Command
{
    char *name;
    void (*action)(char **args, int argc);
} Command;

o name: 实际命令(如"say""date"

o action: 指向要执行的函数的指针

这种结构对于添加新命令非常方便,无需编写额外的if-else语句。


查看一些命令

让我们看看execute.c文件中实现的一些命令:

say_action

void say_action(char **args, int argc)
{
    if (argc > 1)
    {
        for (int i = 1; i < argc; i++)
        {
            printf("%s ", args[i]);
        }
    }
    printf("\n");
}

简单地回显用户输入的内容——一个很好的测试命令。

date_command

给你当前的日期和时间——根据标志如-dy-dm等,可以选择性地分解为年、月、日、小时、分钟或秒。

clone_file_command

使用二进制读写将文件从一个位置复制到另一个位置。

cut_file_command

剪切文件(移动它)到新位置并删除原始文件——使用文件流和路径操作。

list_of_directory

以树状格式递归列出目录内容。真的很酷!


函数指针魔法

使用函数指针而不是条件语句使设计更具可扩展性。你可以像这样添加新命令:

{"new_command", new_command_action}

…并将其实现为常规函数。完成!


内存考虑

每个命令函数都接受char **argsint argc——就像main(int argc, char **argv)一样——保持熟悉和灵活。

另外,如主循环所示:

free_args(args, argc);
free(command);

每次命令执行后都会正确清理内存


为什么采用这种方法?

模块化设计: 每个命令都是自包含的,易于测试或扩展。
动态执行: 可以使用函数指针高效地分派命令。
用户友好的反馈: 优雅地处理无效输入。
可扩展结构: 在主文件中添加新命令只需要2行!


总结:构建自定义Shell

在过去的三部分中,我们用C构建了一个功能性的、模块化的shell:

o 第1部分: 动态读取用户输入

o 第2部分: 将输入解析为参数

o 第3部分(这一部分): 根据用户输入执行命令

Tags:

最近发表
标签列表