热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux0.11shell程序跑起来了38

Linux0.11-shell程序跑起来了-38Shell程序跑起来了转载Shell程序跑起来了书接上回,上回书咱们说到,Linux通过缺页中断处理过

Linux 0.11-shell 程序跑起来了-38

  • Shell程序跑起来了
  • 转载




Shell程序跑起来了

书接上回,上回书咱们说到,Linux 通过缺页中断处理过程,将 /bin/sh 的代码从硬盘加载到了内存,此时便可以正式执行 shell 程序了。

这个 shell 程序,也就是 Linux 0.11 中要执行的这个 /bin/sh 程序,它的源码并没有体现在 Linux 0.11 源码中。

也可以说,不论这个 /bin/sh 是个啥文件,哪怕只是个 hello world 程序,Linux 0.11 的启动过程中也会傻傻地去执行它。

但同时,shell 又是一个我们再熟悉不过的东西了。

在我的腾讯云服务器上(用 Termius 连接),它是这个样子的。

图片

在我的 Ubuntu 16.04 虚拟机上,它是这个样子的。

图片

在我的 mac 电脑上,它是这个样子的。

图片

没错,它就是我们通常说的那个命令行黑窗口。

当然 shell 只是一个标准,具体的实现可以有很多,比如在我的 Ubuntu 16.04 上,具体的 shell 实现是 bash。

flash:~$ echo $SHELL
/bin/bash

而在我的 mac 上,具体的实现是 zsh。

~ echo $SHELL
/bin/zsh

当然,默认的 shell 实现也可以手动进行设置并更改。

还有个有意思的事,shell 前面的提示符,是否可以修改呢?

我的腾讯云服务器上,提示符是

[root@VM-24-11-centos ~]#

我的 Ubuntu 虚拟机上,提示符是

flash:~$

我的 mac 电脑上更简单,提示符是

~

我现在觉得我那个腾讯云服务器上的提示符太长了怎么办?我们先查看一个变量 PS1 的值

[root@VM-24-11-centos ~]# echo $PS1
[\u@\h \W]\$

然后,我们直接把这个值给改了。

[root@VM-24-11-centos ~]# echo $PS1
[\u@\h \W]\$
[root@VM-24-11-centos ~]# PS1=[呵呵呵]
[呵呵呵]

可以看到神奇的事情发生了,前面的提示符变成了我们自己定义的样子。

其实我就想说,shell 程序也仅仅是个程序而已,它的输出,它的输入,它的执行逻辑,是完全可以通过阅读程序源码来知道的,和一个普通的程序并没有任何区别。

好了,接下来我们就阅读一下 shell 程序的源码,只需要找到它的一个具体实现即可。但是 bash,zsh 等实现都过于复杂,很多东西对于我们学习完全没必要。

所以这里我通过一个非常非常精简的 shell 实现,即 xv6 里的 shell 实现为例,来进行讲解。

xv6 是一个非常非常经典且简单的操作系统,是由麻省理工学院为操作系统工程的课程开发的一个教学目的的操作系统,所以非常适合操作系统的学习。

图片

而在它的源代码中,又恰好实现了一个简单的 shell 程序,所以阅读它的代码,对我们这个系列课程来说,简直再合适不过了。

图片

看到没,甚至在这么一个小小的截图里,已经可以完整展示 sh.c 里全部的 main 方法代码了。

但我仍然十分贪婪,即便是这么短的代码,我也帮你把一些多余的校验逻辑去掉,再去掉关于 cd 命令的特殊处理分支,来一个最干净的版本。

// xv6-public sh.c
int main(void) {static char buf[100];// 读取命令while(getcmd(buf, sizeof(buf)) >= 0){// 创建新进程if(fork() == 0)// 执行命令runcmd(parsecmd(buf));// 等待进程退出wait();}
}

看,shell 程序变得异常简单了!

总得来说,shell 程序就是个死循环,它永远不会自己退出,除非我们手动终止了这个 shell 进程。

在死循环里面,shell 就是不断读取(getcmd)我们用户输入的命令,创建一个新的进程(fork),在新进程里执行(runcmd)刚刚读取到的命令,最后等待(wait)进程退出,再次进入读取下一条命令的循环中。

由此你是不是也感受到了 xv6 源码的简单之美,真的是见名知意,当你跟我走完这个 Linux 0.11 之旅后,再去阅读 xv6 的源码你会觉得非常舒服,因为 Linux 0.11 很多地方都用了非常骚的编码技巧,使得理解起来很困难,谁让 Linus 这么特立独行呢。

我们之前说过 shell 就是不断 fork + execve 完成执行一个新程序的功能的,那 execve 在哪呢?

那我们就要看执行命令的 runcmd 代码了。

void runcmd(struct cmd *cmd) {...struct execcmd ecmd = (struct execcmd*)cmd;...exec(ecmd->argv[0], ecmd->argv);...
}

这里我又省略了很多代码,比如遇到管道命令 PIPE,遇到命令集合 LIST 时的处理逻辑,我们仅仅看单纯执行一条命令的逻辑。

可以看到,就是简简单单调用了个 exec 函数,这个 exec 是 xv6 代码里的名字,在 Linux 0.11 里就是我们在 第35回 | execve 加载并执行 shell 程序 里讲的 execve 函数。

shell 执行一个我们所指定的程序,就和我们在 Linux 0.11 里通过 fork + execve 函数执行了 /bin/sh 程序是一个道理。

你看,fork 和 execve 函数你一旦懂了,shell 程序的原理你就直接秒懂了。而 fork 和 execve 函数的原理,其实如果你非常熟练地掌握中断、虚拟内存、文件系统、进程调度等更为底层的基础知识,其实也不难理解。

所以,根基真的很重要,本回已经到操作系统启动流程的最后一哆嗦了,如果你现在感觉十分混乱,最好的办法就是,不断去啃之前那些你认为"无聊的"、"没用的"章节。

好了,今天的 shell 就到这里了,毕竟我们是讲 Linux 0.11 核心流程的系列,不必过多深入 shell 这个应用程序。

接下来有个问题,shell 程序执行了,操作系统就结束了么?

欲知后事如何,且听下回分解。



转载

本文转载至闪客图解操作系统系列文章


推荐阅读
  • hlg_oj_1116_选美大赛这题是最长子序列,然后再求出路径就可以了。开始写的比较乱,用数组什么的,后来用了指针就好办了。现在把代码贴 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • Java 中的十进制样式 getZeroDigit()方法,示例 ... [详细]
  • 洛谷 P4009 汽车加油行驶问题 解析
    探讨了经典算法题目——汽车加油行驶问题,通过网络流和费用流的视角,深入解析了该问题的解决方案。本文将详细阐述如何利用最短路径算法解决这一问题,并提供详细的代码实现。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 在使用 Cacti 进行监控时,发现已运行的转码机未产生流量,导致 Cacti 监控界面显示该转码机处于宕机状态。进一步检查 Cacti 日志,发现数据库中存在 SQL 查询失败的问题,错误代码为 145。此问题可能是由于数据库表损坏或索引失效所致,建议对相关表进行修复操作以恢复监控功能。 ... [详细]
  • 如何在Linux中配置环境变量:命令与脚本详解
    请关注本头条号,每天坚持更新原创干货技术文章。当您在Linux命令行上键入命令时,您实际是在告诉shell运行指定名称的可执行文件。在Linux中,这些可执行程序通常位于系统上的几 ... [详细]
  • Beetl是一款先进的Java模板引擎,以其丰富的功能、直观的语法、卓越的性能和易于维护的特点著称。它不仅适用于高响应需求的大型网站,也适合功能复杂的CMS管理系统,提供了一种全新的模板开发体验。 ... [详细]
  • 本问题涉及在给定的无向图中寻找一个至少包含三个节点的环,该环上的节点不重复,并且环上所有边的长度之和最小。目标是找到并输出这个最小环的具体方案。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中安装 Python 3.7 的步骤,包括编译工具的安装、Python 3.7 源码的下载与编译、软链接的创建以及常见错误的处理方法。 ... [详细]
  • 构建个人多节点Linux环境(CodeSheep)
    本文介绍如何通过虚拟机搭建一个多节点的Linux环境,这对于学习、实验和项目部署都具有重要意义。文章详细讲解了网络IP设置、节点间通信等关键步骤。 ... [详细]
  • CentOS7通过RealVNC实现多人使用服务器桌面
    背景:公司研发团队通过VNC登录到CentOS服务器的桌面实现软件开发工作为防止数据外泄,需要在RealVNC设置禁止传输文件、访问粘贴板等策略过程&# ... [详细]
  • Centos7 Tomcat9 安装笔记
    centos7,tom ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
author-avatar
无味18_380
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有