Linux:minishell

目录

1.实现逻辑

2.代码及效果展示

1.打印字符串提示用户输入指令

2.父进程拆解指令

3.子进程执行指令,父进程等待结果

4.效果

3.实现过程中遇到的问题

1.打印字符串的时候不显示

2.多换了一行

3.cd路径无效

4.优化

1.ll指令

2.给文件或目录加上颜色

代码链接


模拟实现shell程序

所用知识

1.基础的C语言知识,fgets,fflush(刷新缓冲区)

2.字符串相关的函数:strtok

3.进程的创建(fork)进程的等待(waitpid) 进程的替换(exec*函数) 进程的终止(exit)

shell运行原理

父进程等待&&解析指令,子进程执行指令

1.实现逻辑

shell需要一直等待用户输入指令,然后执行指令,因此写一个死循环

1.打印出字符串"[zy@localhost myshell]# "提示用户输入信息

--使用fflush刷新缓冲区

2.父进程分析指令

--定义一个字符数组cmd来存放完整的指令(使用fgets函数,将命令读取到字符数组cmd中)

--定义一个字符指针数组来存放拆解后的指令(使用strtok函数,将其拆解)

--创建子进程执行指令,然后阻塞等待执行的结果

3.子进程执行指令

--调用execvp函数,执行拆解好的指令

2.代码及效果展示

--预备工作

--定义一个字符数组cmd来存放完整的指令(使用fgets函数,将命令读取到字符数组cmd中)

--定义一个字符指针数组来存放拆解后的指令(使用strtok函数,将其拆解)

--定义一个分割符(使用#define定义SEP为空格)

1.打印字符串提示用户输入指令

复制代码
 19     //1.打印字符串,提示用户输入指令                                                                                                        
 20     printf("[zy@localhost myshell]# ");                                                                                                    
 21     fflush(stdout);                                                                                                                        
 22     memset(cmd,'\0',sizeof(cmd));//初始化                                                                                                  
 23                                                                                                                                            
 24     if(fgets(cmd,sizeof(cmd),stdin)==NULL) continue;//读取用户输入的指令,若输入为NULL直接跳过                                             
 25     cmd[strlen(cmd)-1] = '\0';//由于是从键盘读取,会读取到\n,我们将其置为\0 

--fflush是用来刷新缓冲区的

--memset将cmd数组初始化,也清除了上一次输入的指令

--fgets函数:参数:char *str,int num ,FILE* stream

1.存储从输入流中读取的字符串 2.读取的最大字符数 3.从那读

2.父进程拆解指令

代码:

复制代码
 27     //2.拆解指令,放进g_argv中,后面调用execvp的时候直接传递                                                                                      
 28     int index = 0;                                                                                                                              
 29     g_argv[index++] = strtok(cmd,SEP);                                                                                                          
 30     while(g_argv[index++]=strtok(NULL,SEP)); 

--strtok:参数:char* str , const char * strDelimit (要分割的字符串,用来分割的字符)

第一次调用后,下一次还要继续分割这个字符,传递NULL即可,它会记录分割点的位置

3.子进程执行指令,父进程等待结果

4.效果

3.实现过程中遇到的问题

1.打印字符串的时候不显示

字符串不显示

使用fflush,刷新缓冲区即可

效果:

2.多换了一行

代码:

这里可以看到多换了一行

原因:fgets从键盘读取数据会把\n也读进cmd中,我们需要把\n置为'\0'

方法:cmd[strlen(cmd)-1] = '\0'; strlen遇到\0就不在计数了,通过其找到'\n'的位置

效果:

3.cd路径无效

原因

1.子进程是父进程的一份拷贝,直接用pwd显示的路径就是父进程的路径

2.如果使用cd指令,exec函数执行完就退出了,再执行pwd就是重新调用,父进程会生成一个新的子进程, 显示的是父进程的路径

解决:加一个判断,如果是cd命令,直接使用chdir改变当前父进程的路径

复制代码
   33     if(strcmp(g_argv[0],"cd")==0)//特殊处理一下cd指令
   34     {
   35       if(g_argv[1]!=NULL) chdir(g_argv[1]); 
   36       continue;
   37     }

解决:

4.优化

1.ll指令

解决:特殊处理一下

复制代码
   32     if(strcmp(g_argv[0],"ll")==0)//特殊处理一下ll指令
   33     {
   34       g_argv[0] = (char*)"ls";
   35       g_argv[index++] = (char*)"-l";                                                                                                                              
   36     }

原来:

解决:

2.给文件或目录加上颜色

思路:特殊处理

这是ls加上颜色的指令:

代码:

复制代码
   32     if(strcmp(g_argv[0],"ls")==0)//特殊处理ls指令,为其加上颜色
   33     {
   34       g_argv[index++] = (char*)"--color=auto";
   35     }
   36 
   37     if(strcmp(g_argv[0],"ll")==0)//特殊处理ll指令
   38     {
   39       g_argv[0] = (char*)"ls";
   40       g_argv[index++] = (char*)"--color=auto";
   41       g_argv[index++] = (char*)"-l";

效果:

代码链接

链接:myshell · 朱垚/C++与Linux实例 - 码云 - 开源中国 (gitee.com)

相关推荐
ALex_zry40 分钟前
SSH主机密钥验证失败:全面解决方案与技术手册
运维·ssh
厦门辰迈智慧科技有限公司2 小时前
城市排水管网流量监测系统解决方案
运维·服务器
我没有开挂2 小时前
旧 docker 版本通过 nvkind 搭建虚拟多节点 gpu 集群的坑
运维·docker·容器
qq_339282232 小时前
centos中libc.so.6No such file的解决方式
linux·运维·centos
leoufung2 小时前
ECPF 简介
linux·网络·kernel
小鸡,啄米3 小时前
centos9安装docker 配置docker代理
运维·docker·容器
水银嘻嘻3 小时前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
在肯德基吃麻辣烫3 小时前
Netdata在Ubuntu环境下的安装与配置:构建实时系统监控与性能分析平台
linux·运维·ubuntu
国际云,接待4 小时前
云服务器的运用自如
服务器·架构·云计算·腾讯云·量子计算
不念霉运4 小时前
Gitee DevOps:中国企业数字化转型的“本土化加速器“
运维·gitee·团队开发·代码规范·devops·代码复审