Linux之模拟shell命令行解释器

文章目录

  • 前言
  • 一、输出提示符
    • 1.实际
    • 2.模拟
  • 二、输入指令、获取指令
    • 1.实际
    • 2.模拟
  • 三、fork创建子进程
  • 四、内建命令
  • 五、代码实现
  • 总结


前言

本文是基于前面介绍过的关于进程创建、进程终止、进程等待、进程替换等知识,尝试做的一个简单的shell命令解释器。


一、输出提示符

1.实际

在这里插入图片描述

2.模拟

printf("用户名@主机名 当前路径#");
fflush(std);

此处没有“\n”,会有缓冲区的问题,因此要用fflush(std);来刷新缓冲区

二、输入指令、获取指令

1.实际

在这里插入图片描述

2.模拟

  1. 输入
char lineCommand[NUM];
char* s = fgets(lineCommand,sizeof(lineCommand) - 1,stdin);
assert(s != NULL);
lineCommand[strlen(linCommand) - 1] = 0;

fgets函数获取一行的内容,将内容存在字符数组lineCommand中。
因为fgets获取也会将enter作为'\n’获取,为了避免多打印一行,我们要将最后一个元素重置为'\0'

  1. 获取
strtok(lineCommand," ");

用strtok函数将输入的字符串切割成若干个子串;

strtok函数的参数:第一次传字符串的首地址,之后传NULL即可(会从上次切割的位置继续切割)。

三、fork创建子进程

利用fork创建子进程;
替换函数需要带上v和p,即execvp函数。

为啥要用子进程去执行命令?
答:如果不创建子进程,而是让bash直接去执行进程,会将我们的bash直接替换为其他程序,shell就不能继续正常执行其他指令了(就回不到输入界面了)。

四、内建命令

我们在运行自己写的shell,输入cd ../cd path等命令时,发现路径并没有发生修改,这是为啥?
答:因为我们自己写的shell,执行很多命令都要用fork创建子进程,让子进程去执行。当子进程执行cd命令时,更改的时子进程的工作目录而与父进程无关,因此父进程的路径并不会发生修改。
因此,对于cd命令我们应该用内建命令:该命令不需要子进程执行,而是让bash自己执行。要修改程序的工作目录需要用chdir系统调用。

什么是当前路径?
当前路径就是cwd。
cwd -> 当前进程所在的工作目录(默认是文件存储在磁盘的路径);
exe -> 当前运行的是磁盘路径下的哪个进程。
更改当前进程的工作目录:chdir。(谁调用我,我就更改谁的工作目录)

在这里插入图片描述

五、代码实现

1 #include<stdio.h>2 #include<assert.h>3 #include<string.h>4 #include<unistd.h>5 #include<sys/types.h>6 #include<sys/wait.h>7 #include<stdlib.h>8 #define NUM 10249 #define OPT_NUM 6410 char lineCommand[NUM];11 char* myargv[OPT_NUM];12 int lastCode = 0;13 int lastSig = 0;14 int main()15 {16         while(1)17         {18         printf("用户名@主机名 路径#");19         fflush(stdout);20         char* s = fgets(lineCommand,sizeof(lineCommand) - 1, stdin);21         assert(s != NULL);22         (void)s; 23         lineCommand[strlen(lineCommand) - 1] = 0;24         myargv[0] = strtok(lineCommand," "); 25         int i = 1;26         if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)27         {28                 myargv[i++] = (char*)"--color=auto";29         }       30         while(myargv[i++] = strtok(NULL," "));31         if(myargv[0] != NULL && strcmp(myargv[0], "cd") == 0)32         {33                 if(myargv[1] != NULL) chdir(myargv[1]);34                 continue;35         }       36         if(myargv[0] != NULL && strcmp(myargv[0], "echo") == 0)37         {38                 if(strcmp(myargv[1], "$?") == 0)39                 {40                         printf("%d %d\n", lastCode, lastSig);41                 }       42                 else43                 {44                         printf("%s\n",myargv[1]);45                 }46                 continue;47         }48         #ifdef DEBUG49         for(int i = 0; myargv[i]; ++i)50         {51                 printf("myargv[%d]=%s\n", i, myargv[i]);52         }53         #endif54         pid_t id = fork();55         if(id < 0)56         {57                 perror("fork");58                 exit(1);59         }60         else if(id == 0)61         {62                 //63                 execvp(myargv[0], myargv);64                 exit(1);65         }66         int status = 0;67         pid_t ret = waitpid(id, &status, 0);68         assert(ret > 0);69         (void)ret;70         lastSig = WIFEXITED(status);71         lastCode = WEXITSTATUS(status);72         }73         return 0;74 }

运行:
在这里插入图片描述
文件tt.c
在这里插入图片描述
在这里插入图片描述


总结

以上就是今天要讲的内容,本文介绍了如何实现一个简单的shell解释器。本文作者目前也是正在学习Linux相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/256039.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

360兼容模式、ie浏览器加载不出项目数据

打开页面按钮显示异常&#xff1a; 页面显示多个按钮 原因是&#xff1a; 360兼容模式、ie浏览器不兼容console.log(),从而导致了页面没有走下去&#xff0c;数据没有加载出来。 删除或者注释掉就能正常显示了。

解决vue项目在ie和360兼容模式下显示空白页问题

艰难路程 记一次bug解决&#xff0c;项目不复杂&#xff0c;是一个基于vue-cli3搭建的pc端项目&#xff0c;之前开发都是在谷歌浏览器上运行的&#xff0c;但在开发进入到后半段&#xff0c;经理说&#xff0c;项目需要在360兼容模式下展示&#xff0c;这时候发现项目在360兼容…

html 让360浏览器兼容模式,360浏览器兼容模式的设置方法

我们在使用360win7w.com/jiaocheng/3735.html target=_blank class=infotextkey>浏览器的时候,有的小伙伴可能就想要打开浏览器的兼容模式。那么对于360浏览器兼容模式设置方法,小编觉得我们可以在浏览器的有上角找到闪电标志点开切换即可,也可以在设置中进行调整即可。详…

SAP 主索引和二级索引

透明表索引有两种&#xff1a;分别是主索引和二级索引。 主索引是在我们创建表激活后由系统自动创建的&#xff0c;这个我们不能修改&#xff1b;二级索引可以我们自己创建。 主索引是表的主键&#xff0c;二级索引可以根据你自己需要用到表的任何字段的组合来创建。 在使用二级…

pandas索引和复合索引

一、获取索引 index import pandas as ps import numpy as npa1 ps.DataFrame(np.arange(8).reshape((2,4)),columns["A","B","C","D"],index["a","b"]) print(a1,"\n","#"*50)# A B …

索引格式的图片在PS软件中无法操作,怎么解决?

在计算机上打开photoshop&#xff0c;发现是索引模式&#xff0c;无法进行操作。应该修改为RGB模式即可。 索引模式图像&#xff0c;索引模式主要用于网络上以及某些对图像像素有严格要求的地方等的图像传输。Photoshop中的索引模式图像无法修改&#xff0c;必须更改为背景或图…

索引的概念和创建索引例子

1 索引的概念 索引是一个单独的、物理的数据库结构&#xff0c;它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。表的存储由两部分组成&#xff0c;一部分用来存放数据页面&#xff0c;另一部分存放索引页面。通常&#xff0c;索引页面…

主索引和二级索引区别,并创建一个二级索引

透明表索引有两种&#xff1a;分别是主索引和二级索引。 主索引是在我们创建表激活后由系统自动创建的&#xff0c;这个我们不能修改&#xff1b;二级索引可以我们自己创建。主索引是表的主键&#xff0c;二级索引可以根据你自己需要用到表的任何字段的组合来创建。在使用二级索…

【个人笔记】Photoshop打开图片为”索引颜色“模式

如下图&#xff1a; 遇到这种问题无法编辑&#xff0c;”图像“——”模式“——将”索引颜色“改为”RGB颜色“ 然后就可以编辑了。

Axure9汉化

Axure9汉化 Axure下载安装后是英文版本&#xff0c;使用的时候会有点别扭&#xff0c;看一个单词需要反应一段时间&#xff0c;影响工作效率。 下面就是如何汉化的步骤&#xff1a;1-5 1、首先我们需要根据你的版本下载汉化包&#xff0c;打开axure ,点击help--About Axure …

若干tif文件转换成pdf

方案1&#xff1a; &#xff08;1&#xff09;用imageJ把多个tif文件弄成一个整合的tif文件&#xff1b; &#xff08;2&#xff09;然后用smaurt打开&#xff0c;另存为pdf 失败告终。 方案二&#xff1a;留个坑&#xff0c;没找到合适的解决方案。

华为OD机试真题B卷 Java 实现【寻找关键钥匙】,附详细解题思路

一、题目描述 小强正在参加《密室逃生》游戏&#xff0c;当前关卡要求找到符合给定 密码K&#xff08;升序的不重复小写字母组成&#xff09;的箱子&#xff0c;并给出箱子编号&#xff0c;箱子编号为1~N。 每个箱子中都有一个字符串s&#xff0c;字符串由大写字母&#xff0…

LC-1130. 叶值的最小代价生成树(贪心、区间DP、单调栈)

1130. 叶值的最小代价生成树 难度中等272 给你一个正整数数组 arr&#xff0c;考虑所有满足以下条件的二叉树&#xff1a; 每个节点都有 0 个或是 2 个子节点。数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。每个非叶节点的值等于其左子树和右子树中叶节点的最大…

人工智能粒子群优化三大算法

粒子群优化是以邻域原理&#xff08;neighborhood principle&#xff09;为基础进行操作的&#xff0c;该原理来源于社会网络结构研究中。驱动粒子群优化的特性是社会交互作用。群中的个体&#xff08;粒子&#xff09;相互学习&#xff0c;而且基于获得的知识移动到更相似于它…

Golang每日一练(leetDay0082) 用队列实现栈、用栈实现队列

目录 225. 用队列实现栈 Implement Stack Using Queues &#x1f31f; 232. 用栈实现队列 Implement Queue Using Stacks &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 …

PS07海报截剪和切片(标尺使用),PS08图框工具(剪贴蒙版),PS09吸管工具组(颜色取样)

PS07海报截剪和切片&#xff08;标尺使用&#xff09; PS08图框工具&#xff08;剪贴蒙版&#xff09;PS09吸管工具组&#xff08;颜色取样&#xff09;

ps制作太极图

最终效果&#xff1a; 操作步骤&#xff1a; (1)、 新建文件-800*800px&#xff0c;打开标尺&#xff0c;新建参考线、得到中心点。 ctrlr 打开标尺&#xff0c; 学会 拉 标尺线&#xff0c; 拉出两条标尺线&#xff0c;让其水平、垂直相交。 (2)、 椭圆选框-以中心点绘制正圆…

用ps制作太极图

操作步骤&#xff1a; (1)、 新建文件-800*800px&#xff0c;打开标尺&#xff0c;新建参考线、得到中心点。 ctrlr 打开标尺&#xff0c; 学会 拉 标尺线&#xff0c; 拉出两条标尺线&#xff0c;让其水平、垂直相交。 (2)、 椭圆选框-以中心点绘制正圆&#xff08;按AltShi…

ps中怎样测量标尺线之间的距离及怎样切换距离单位

2019独角兽企业重金招聘Python工程师标准>>> 首先说一下&#xff0c;我用ps还不是很熟练&#xff0c;所以都是初级的问题&#xff0c;希望各位ps大神莫喷~~首先说一下怎么找到标尺呢&#xff1f;打开ps后&#xff0c;最上面有一个视图&#xff0c;点击后将标尺选项前…

前端ps基本操作

在还原设计时,我们需要使用 photoshop打开sd格式的设计,作为的工程师,我们不要太多的ps技巧,只需要了 一些简单的基本操作即可 1、alt 滚轮缩放放图片 2、空格鼠标左健拖动图片 3、shiftm切换选取工具,使用鼠标左键选择,ctrld可以取消选取 4、F8查看信息,可以查看选取内容的…