用C语言构建简单Shell:系统编程初学者指南(3-3)
我如何用C语言构建简单Shell——系统编程初学者指南 (3/3)
#cli #c #systemprogramming #memorymanagement
第3部分:在自定义Shell中执行命令(C编程)
在我的自定义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]);
命令匹配: Shell遍历Command结构体数组,将输入与注册的命令名称进行比较。
函数指针: 如果找到匹配项,通过指针调用相应的函数。
错误反馈: 如果没有找到匹配项,shell通知用户命令未知(故意有个小拼写错误?😉)。
Command结构
每个命令都是一个看起来像这样的结构体:
- typedef struct Command
- {
- char *name;
- void (*action)(char **args, int argc);
- } Command;
name: 实际命令(如"say"或"date")
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 args和int argc——就像main(int argc, char argv)一样——保持熟悉和灵活。
另外,如主循环所示:
- free_args(args, argc);
- free(command);
每次命令执行后都会正确清理内存 ✅
为什么采用这种方法?
📌 模块化设计: 每个命令都是自包含的,易于测试或扩展。
📌 动态执行: 可以使用函数指针高效地分派命令。
📌 用户友好的反馈: 优雅地处理无效输入。
📌 可扩展结构: 在主文件中添加新命令只需要2行!
总结:构建自定义Shell 🧠
在过去的三部分中,我们用C构建了一个功能性的、模块化的shell:
✅ 第1部分: 动态读取用户输入
✅ 第2部分: 将输入解析为参数
✅ 第3部分(这一部分): 根据用户输入执行命令
