Shell 的实现

Shell的本质是一个用户交互程序,它读取、解析并执行用户输入的命令。

程序而非内核组件:Shell只是一个普通用户态程序,它通过 forkexecvewaitpid 等系统调用实现命令执行和作业控制。

内置函数 vs 外置函数

  • 内置命令(如 cdexitjobs):Shell 自身直接处理,不创建新进程。
  • 外置命令(如 lsgccvim):Shell 通过 fork 创建子进程,子进程调用 execve 加载并执行对应程序。

eval函数:Shell的核心逻辑是一个命令分发函数(通常称为 eval),负责解析命令字符串,区分内置/外置命令,并调用相应执行路径。

前台作业 vs 后台作业

  • 前台作业:Shell 创建子进程后调用 waitpid 阻塞等待其完成。执行期间用户无法输入新命令。
  • 后台作业(命令后加 &):Shell 创建子进程后等待,立即返回准备接收下一条命令。

后台作业的回收不能通过阻塞的 waitpid 实现,否则Shell会卡住。解决方案是使用信号——子进程终止时内核向父进程(Shell)发送 SIGCHLD 信号,Shell在信号处理程序中调用 waitpid 实现非阻塞回收。

链接到