用C语言构建简单Shell:系统编程初学者指南(3-3)
东城
·
2026-01-31
我如何用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部分
(这一部分):
根据用户输入执行命令
Aa