模拟shell

简介: 模拟shell

前言


通过替换函数 execp使用命令行参数


01d7b1e8254189c2bdcc1d3dbf418ec7_3834550930ca42c694f0dc2dd5fc23a6.png

9475487972538555e8ac9672afed75dd_fa4f213c44144a6eb47f72eed271249b.png

命令行参数可转换为一个个指令选项


./execvp pwd->"./execvp" "pwd"


既然如此,如果能去掉前面地./execvp,那么后面的执行以及选项是不是就和命令行解释器一样


按照这个思路,下面来实现模拟命令行解释器


输入命令行参数


由于是在键盘上输入命令行参数,所以采取函数fgets,来获取命令行参数


char *fgets(char *s, int size, FILE *stream)


这里还是存在一个问题,该函数是获取所有从键盘输入的字符串,就连最后的回车也会被获取,这样就会造成,数据打印出来之后,会多出一行


所以需要将最后一个字符置为\0


linecommad[strlen(linecommand)-1]=0;


命令行切割


命令行是字符串,需要将其切割成一个个命令选项

这里采取函数 strtok


char *strtok(char *str, const char *delim);


以 为切割符,先将第一个字符放入指针数组第一个位置myargv[0]中;随后的字符通过循环依次放入数组中


"ls -l -a"->"ls""-l""-a"
myargv[0]=strtok(linecommand," ");
while(myargv[i++]=strtok(NULL," "));


测试是否成功


6198b7a1615725f28230581b71025e58_20f15f73dbb24879a213b383df51e557.png

515076f012c651ca23f2872bb7f9f2c5_0d1c0e70055c408195bc036bf7da24c9.png

测试结果很成功,由于测试不止是一次,所以可以设置为循环,并且还需要添加一些其他的功能


改进


ls命令加颜色


先判断如果第一个字符就是 ls命令,那么就将其赋予颜色


if(myargv[0]!=NULL&&strcmp(myargv[0],"ls")==0)                                                                                                                       
{       
     myargv[i++]=(char*)"--color=auto";                                                                          
}


618b3aa52099b2a7f8bc1e0b54da25eb_ceb3ccd7d26f4cbda8427d3f890fde86.png


内建(内置命令)


先观察下列指令


9d58dc5ec9b458b26eae28327eb25f4b_05c800db8a9242c185c6402e35056c12.png


为什么指令没有效果呢???


先来学习什么是当前路径,当一个程序正在运行时,查看进程相关信息


a8984db529718e41a1bfd9f1a854be19_1f666722950d42119439289db2d9a48c.png

214887cc746fbac562d86e1e2936bcc2_45605e20931142cb958eb55db13395d8.png


先介绍这两个特别的信息exe当前进程执行的是磁盘路径下的哪个程序;cwd当前进程的工作目录


pwd指令所显示的就是当前工作目录

模拟实现的命令行解释器在cd ..时路径之所以没有发生变化是因为,进程先通过fork()创建子进程,子进程执行的cd ..,子进程也有自己的工作目录,所更改的是子进程的目录,所以并不是路径没有改变,只是没有看到而已。


为了能够看到父进程的工作目录发生改变,当命令是cd时不创建子进程,直接让命令行解释器去执行命令,而这种不需要子进程来执行的命令也称为内建/内置命令


可以进行如下操作


while(myargv[i++]=strtok(NULL," "));
     if(myargv[0]!=NULL&&strcmp(myargv[0],"cd")==0)
     {
          if(myargv[1]!=NULL)
          {
             chdir(myargv[1]);
          }
     }


这里的函数chdir可以改变工作目录


int chdir(const char *path);


c215d606d08f90455c4bc6e7397077ef_947c0452abf548dbbdda5bdf4483b35f.png


3a5bcc3c2d61023ee8510567308cf7f2_cfd2aacc6d3541a18f979e1fb6a7fb21.png


运行结果符合预期


总结


命令行解释器的模拟实现主要是依赖于替换函数,其他的细节也需要注意,此版本的解释器还有所欠缺,待补充的功能还有很多。


目录
相关文章
|
1月前
|
Shell 应用服务中间件 nginx
shell学习(七) 【shell 函数】
shell学习(七) 【shell 函数】
12 1
|
6月前
|
Shell
强大好用的shell:shell的工作原理是什么
Shell的工作原理可以简要概括为以下几个步骤: 1.命令行输入:用户在命令行界面输入命令。 2.命令解析:Shell接收用户的输入,并对命令进行解析。这个过程包括解析命令名、参数、选项等,将其转换成计算机可以理解的形式。 3.命令执行:解析完成后,Shell会执行相应的命令。这通常涉及到调用系统调用或者启动新的进程来执行命令。 4.结果输出:命令执行完成后,Shell将结果输出到命令行界面,供用户查看。
|
9月前
|
监控 关系型数据库 MySQL
Shell脚本案例大全
Shell脚本案例大全
63 1
|
5月前
|
小程序 Shell Linux
shell(二)第一个shell程序
前文我们了解了shell编程的具体情况。那么这里,我们开始shell编程的第一次尝试。
27 1
|
6月前
|
机器学习/深度学习 Shell
我们一起来学Shell - shell的循环控制
我们一起来学Shell - shell的循环控制
47 0
|
10月前
|
Unix Shell Linux
shell中需要掌握的几个信号(shell 进阶)
shell中需要掌握的几个信号(shell 进阶)
71 0
|
Java Shell Linux
shell 基础
shell 基础
98 0
|
Unix Shell Linux
Shell - 基础篇(上)
Shell - 基础篇(上)
96 0
Shell - 基础篇(上)
|
缓存 Shell Linux
Shell - 基础篇(下)
Shell - 基础篇(下)
59 0
Shell - 基础篇(下)