目录
整体框架分析
考虑下面这个与shell典型的互动:
[xzy@ecs-333953 date16]$ ls makefile mycmd mycmd.cpp myexec myexec.c test.py [xzy@ecs-333953 date16]$ ps PID TTY TIME CMD 21919 pts/0 00:00:00 bash 21947 pts/0 00:00:00 ps [xzy@ecs-333953 date16]$用下图的时间轴来表示事件的发生次序。其中时间从左到右。shell由表示为bash的方块代表,它随着时间的流逝从左向右移动。shell从用户读入字符串"ls"。shell建立一个新的进程,然后在那个进程中运行ls程序并等待那个进程结束。
然后shell读取新的一行输入,建立一个新的进程,在这个进程中运行程序并等待这个进程结束,所以要写一个shell,需要循环以下过程:
- 获取命令行
- 解析命令行
- 建立一个子进程(fork)
- 替换子进程(execvp)
- 等待子进程退出(wait)
根据这些思路,和我们前面学习的技术,就可以自己来实现一个shell了。
代码演示
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/wait.h> #include<sys/types.h> #define SEP " "//分隔符 #define NUM 1024 #define SIZE 128 char command_line[NUM]; char* command_args[SIZE]; char env_buffer[NUM];//for test //对应上层的内建命令 int ChangeDir(const char* new_path) { chdir(new_path); return 0;//调用成功 } void PutEnvInMyShell(char* new_env) { putenv(new_env); } int main() { //shell本质就是一个死循环 while (1) { //1、显示提示符 printf("[张三@我的主机名 当前目录]# "); fflush(stdout); //2、获取用户输入 memset(command_line, '\0', sizeof(command_line) * sizeof(char)); fgets(command_line, NUM, stdin);//键盘,标准输入,stdin,获取到的是C风格的字符串,'\0'结尾 command_line[strlen(command_line) - 1] = '\0';//清空回车键的\n //3、"ls -a -l -i" -> "ls" "-a" "-l" "-i" 字符串切分 command_args[0] = strtok(command_line, SEP); int index = 1; //给ls命令添加颜色 if (strcmp(command_args[0]/*程序名*/, "ls") == 0) { command_args[index++] = (char*)"--color=auto"; } // = 是故意这么写的 // strtok截取成功,返回字符串起始地址;截取失败,返回NULL whil

文章介绍了如何使用C语言实现一个简单的shell,包括获取用户输入、字符串切分、内建命令处理(如cd和export)、创建子进程以及使用execvp进行程序替换。示例代码展示了关键的函数和逻辑,强调了内建命令处理和环境变量管理的重要性。

最低0.47元/天 解锁文章
6728

被折叠的 条评论
为什么被折叠?



