自建网站推广方式,久久建筑网账号,拓者设计吧会员有啥区别,不用域名做自己的网站文章目录 makefilemybash.c 代码逻辑框架#xff08;重要的是#xff0c;边写边查#xff01;#xff09;
命令行提示符#xff0c;fflush 刷新显示获取 输入的 有效字符串#xff0c;定义一个字符数组#xff0c;用 fgets 从键盘上获取#xff08;注意处理命令行输入… 文章目录 makefilemybash.c 代码逻辑框架重要的是边写边查
命令行提示符fflush 刷新显示获取 输入的 有效字符串定义一个字符数组用 fgets 从键盘上获取注意处理命令行输入时的回车字符串切割C语言函数 strtok子串保存到指针数组创建子进程执行代码
细节 ls 的配色方案 内建命令的处理
cd .. cd / 这样的命令需要让 bash 自己执行的叫做 内建命令 / 内置命令export一般用户自定义的环境变量在 bash 中要用户自己来进行维护不要用一个经常被覆盖的缓冲区来保存环境变量env我们一般需要 env 时都要查看的是自己进程的环境列表这里就是查看 bash 的环境列表。echo利用指针查找和输出echo $?
其实我们之前提到过的几乎所有环境变量命令都是 内建命令。 makefile mybash:mybash.cgcc -o $ $^
.PHONY:clean
clean:rm -f mybashmybash.c #include stdio.h
#include string.h
#include stdlib.h
#include assert.h
#include unistd.h
#include sys/types.h
#include sys/wait.h#define MAX 1024
#define ARGC 64
#define SEP int split(char *commandstr, char *argv[])
{assert(commandstr);assert(argv);argv[0] strtok(commandstr, SEP);if(argv[0] NULL) return -1;int i 1;while((argv[i] strtok(NULL, SEP)));//int i 1;//while(1)//{// argv[i] strtok(NULL, SEP);// if(argv[i] NULL) break;// i;//}return 0;
}void debugPrint(char *argv[])
{for(int i 0; argv[i]; i){printf(%d: %s\n, i, argv[i]);}
}void showEnv()
{extern char **environ;for(int i 0; environ[i]; i) printf(%d:%s\n, i, environ[i]);
}int main()
{//当我们在进行 env 查看的时候我们想查的是谁的环境变量列表父进程 bash 的环境变量列表int last_exit 0;char myenv[32][256];int env_index 0;while(1){char commandstr[MAX] {0}; // 命令行输入的完整字符串char *argv[ARGC] {NULL}; // 命令行输入的子串// 1printf([Stellahostname currpath]# );fflush(stdout); // 把数据从缓冲区刷新显示出来// 2char *s fgets(commandstr, sizeof(commandstr), stdin);assert(s);(void)s; // 保证在release方式发布的时候因为去掉assert了所以s就没有被使用而带来的编译告警, 什么都没做但是充当一次使用// abcd\n\0commandstr[strlen(commandstr)-1] \0;// 3// ls -a -l - ls -a -lint n split(commandstr, argv);if(n ! 0) continue;//debugPrint(argv);// 1【添加 ls 命令的配色方案】if(strcmp(argv[0], ls) 0) {int pos 0;while(argv[pos]) pos;argv[pos] (char*)--colorauto;加配色方案argv[pos] NULL; // 比较安全的做法}// 2【内建命令】// cd .. / cd /: 让bash自己执行的命令我们称之为 内建命令/内置命令if(strcmp(argv[0], cd) 0){//说到底cd 命令重要的表现就如同 bash 自己调用了对应的函数if(argv[1] ! NULL) chdir(argv[1]); // chdir是一个系统调用函数可以改变当前工作路径continue;}else if(strcmp(argv[0], export) 0) // 其实我们之前学习到的所有的(几乎)环境变量命令都是内建命令{if(argv[1] ! NULL){strcpy(myenv[env_index], argv[1]);putenv(myenv[env_index]);}continue;}else if(strcmp(argv[0], env) 0){showEnv();continue;}else if(strcmp(argv[0], echo) 0){// echo $PATHconst char *target_env NULL;if(argv[1][0] $) {if(argv[1][1] ?){printf(%d\n, last_exit);continue;}else target_env getenv(argv[1]1); // abcdefgif(target_env ! NULL) printf(%s%s\n, argv[1]1, target_env);}continue;}// 4// version 1pid_t id fork();assert(id 0);(void)id;if(id 0){if(redir_type ! REDIR_NONE){//1. 存在文件的//2. redir_type获取到//3. dup2;}//childexecvp(argv[0], argv);exit(1);}int status 0;pid_t ret waitpid(id, status, 0);if(ret 0){last_exit WEXITSTATUS(status);}//printf(%s\n, commandstr);}
}