手把手教你编写一个具有基本功能的shell(已开源)

本文详细记录了作者从零开始编写一个名为wshell的shell程序的过程,包括基本功能实现、改善用户体验(如内建命令、readline库的使用)和进阶功能(后台执行、输入/输出重定向、pipe)。文章强调了在实现过程中遇到的问题和解决方案,以及与真实shell的差异。代码已开源在github上,供读者参考学习。
摘要由CSDN通过智能技术生成

刚接触Linux时,对shell总有种神秘感;在对shell的工作原理有所了解之后,便尝试着动手写一个shell。下面是一个从最简单的情况开始,一步步完成一个模拟的shell(我命名之为wshell)的过程。这个所谓的shell和主流的shell还是有不少区别的,最大的区别是它本身不能执行shell脚本、也不能对一些复杂的命令行进行分析——原因很简单,我没有写相应的解释器。如果想自己实现一个简化的shell脚本解释器,如果有编译原理的知识准备,本身不是难事,但是工作量比较大,这里就不完成了,有兴趣的读者可以进行尝试。

  本文是边写代码边记录的,更接近于实现过程的思考过程,因此前面的章节可能和最新版的代码有不小的差别,较大的改动会在后文提出,请注意。不过读者不用担心,这些改动都是在原有基础上的完善和提升,并非推倒重来。可以算作上一篇博文《现代操作系统》精读与思考笔记 第一章 引论的副产品。

  全部的代码开源,已托管至github:https://github.com/vvy/wshell,因此不再往文中大段大段地粘源代码了。第一次用github托管代码,如果有哪里没设置好请告诉我。

  文中所指的和所模仿的shell均指bash。

 

一.基本功能

1.1 程序框架

  首先,shell的基本框架可以用下面的代码概括,这部分代码出自于《现代操作系统(英文第三版)》(Modern Operating Systems)原书P54图1-19,这在上一篇博文《现代操作系统》精读与思考笔记 第一章 引论中已经提到过一次了:

复制代码
#define TRUE 1

while(TRUE) {                  /* repeat forever */
  type_prompt();               /* display prompt on the screen */
  read_command(command,parameters);    /* read input from terminal */
  if(fork()!=0) {               /* fork off child process */
    /* Parent code */
    waitpid(-1,&status,0);         /* wait for child to exit */
   } else {
    /* Child code */
    execve(command,parameters,0);    /* execute command */
  }

}
复制代码

  不怕写不出来代码,就怕没思路。想想这么搞确实能够模拟出shell最基本的行为:接受用户输入<=>执行相应程序,甚至借助execv族函数可以直接给程序传参数。有了这个框架就好办了,把那几个函数给实现不就成了呗?

 

1.2 type_prompt()的实现

  来思考下type_prompt()该如何实现。顾名思义,这个要提供一个终端上的提示符,比如

  

再如

  

   这里的实现需要注意的是,如果当前路径在用户路径下,那么用户路径就用~代替,否则会显示完整路径。分析这两个例子,可以看到输出是这样的形式:“用户名@主机名:路径$”(root权限的#提示符马上提到),对应地:

  • 用户名使用getpwuid(getuid())获得,同时可以获得该用户home目录的路径;
  • 主机名使用gethostname()获得;
  • 路径使用getcwd()获得,如果这个路径包含了该用户home路径,那么使用~把home路径缩略。
  • 对于提示符,模仿bash的风格,对于普通用户使用"$",root用户使用"#",需要检测执行这个wshell的用
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值