🪐🪐🪐欢迎来到程序员餐厅💫💫💫
主厨的主页:Chef‘s blog
所属专栏:青果大战linux
学校开始搞蓝桥的校选了,很好,300块钱不用掏了。昨天还看到一个OS的比赛,可以我这没实力,不然真想去试试。
我相信不少同学(包括我),最开始都理解不了所谓的shell或者说bash到底是什么,他被称之为命令行解释器,他创建子进程,他辅助用户和内核之间进行联系,它本身也是一个进程,这些定义都太抽象了,那么它到底是什么,他又是如何实现这些功能的,要搞清楚这个,其实只要手写一个shell就好了。
为了方便区分,下文对于系统自带的shell我们称之为shell,对于我们自己写的shell我们称之为myshell
思路大纲:
1.首先所谓shell其实就是运行起来的程序,不难发现shell他以运行以来就不会停止,所以可以想到他的代码最外层是一个死循环。
2.循环里面有什么,我们可以分为四个模块 ----【创建命令行提示符】 ------【获取用户命令】------
【分析用户命令】-----【执行用户命令】
接下来我会挨个介绍四个模块。
int main(){
char command_buffer[basesize];
while(true)
{ PrintCommradLine();//打印命令行提示符
GetCommandLine(command_buffer,basesize))//获取命令
ParseCommandLine(command_buffer,(int)strlen(command_buffer));//分析命令
ExecuteCommandLine();//执行命令
}
return 0;
}
创建命令行提示符
不难发现,在我们输入指令的那一行永远都会有一串字符,我们称其为命令行提示符,它由四部分构成:
[用户名+@+主机名+空格+当前路径]+#/$
细节:如果用户是root最后就是#,否则是$
要获取这些信息很简单,我们有很多接口,比如通过getenv从环境变量中获取,或者getcwd从进程信息里找,这里我们先用getenv,后面到cd指令我会在带领大家修改。
string GetUserName(){
string name= getenv("USER");
return name.empty()?"NULL":name;
}
string GetHostName(){
string name= getenv("HOSTNAME");
return name.empty()?"NULL":name;
}
char pwd[basesize];//当前工作路径
char pwdenv[basesize];//PWD的环境变量
string GetPwd(){
string name= getenv("PWD");
return name.empty()?"NULL":name;
}
通过他们三个函数我们就获得用户名,主机名以及当前路径。
接着我们可以通过snprintf函数把他们拼起来,当然这一步你想用c++的string操作也可以,我只提供一种思路,大家可以去充分发挥自己的想象力。
函数介绍:
-
参数s:表示要把内容输出到s数组中
-
参数n:s数组中能被该函数使用的最大空间大小,单位字节
-
参数format:这