返回付费课程总览
C++ POSIX Shell Workshop

用 C++ 从零实现 Shell

进程、管道、信号、作业控制——这些「面试必问」的硬核知识点,最好的学法就是亲手写一个 Shell
1–2 周,从零实现一个可运行、可验收、可写进简历的 mini-shell

约 1–2 周 · 可自由安排首发价¥199¥299

周期

约 1–2 周·自定进度

节奏

5 个 MVP 阶段·每步可验收

交付

可用 mini-shell + 测试脚本

形式

结构化自学 + 图文实战

项目里程碑
可验收
5 阶段通关:章章可验收
进程 / FD / 信号 / 作业控制一条线
单测 + 集成测试:可复现

课程定位

系统编程综合实验 · 项目驱动 · 可复现

Outcomes

你将收获

把 fork/exec/wait 的进程模型讲透:理解“为什么父子进程会同时往下走”。

写出可测试的 tokenizer/parser,把输入稳定地变成 AST,而不是到处 if/else。

真正掌握重定向与管道:close/dup2 的文件描述符接线不再玄学。

搞懂 Ctrl-C/Ctrl-Z 的信号机制:能让 Shell 自己不被打断,并支持前台/后台作业。

沉淀一套可复现的调试与测试方法:单测验证解析,集成测试验证执行。

用 **8 种设计模式** 把代码重构成“工程”:命令/组合/解释器/访问者/策略/状态/适配器/外观模式 + RAII 实战落地。

Teaching Philosophy

教学理念:把 Shell 当作系统课的“总线”

你可以把这门课当作一门“系统编程综合实验”。我们不从语法大全开始,而是从一串很现实的问题开始:

为什么 fork() 之后父子进程会同时往下走?为什么 execve() 一旦成功就回不来了?管道到底是什么,为什么它能把两个进程连起来?

Ctrl-C 为什么会打断程序?它打断的是谁?前台/后台在内核里落在哪些结构上?

每一章都是一个可验收的小里程碑:用单元测试验证 tokenizer/parser,用集成测试验证执行行为,用可观测日志与可复现脚本定位 bug。

每一步都可验证

先让它能用,再逐步逼近真实 Shell 的交互与边界。

解析与执行分层,避免把逻辑写成不可维护的面条代码。

围绕可复现脚本与日志调试,让 bug 有迹可循。

Learning Blueprint

学习路线图

第一阶段 (MVP 1) · 让它先开口

先把 prompt 立起来,再把最简单的外部命令跑起来。你能看到 mini$ ls。

第二阶段 (MVP 2) · 让它听懂人话

让它能稳定地理解输入:tokenizer + parser + 最小 builtin(cd/exit)。你能跑 mini$ cd ..。

第三阶段 (MVP 3) · 把文件描述符拧成乐高

开始做 Shell 最核心的“接线”:重定向与管道。你能跑 mini$ cat a.txt | grep hi > out.txt。

第四阶段 (MVP 4) · 和现实世界的“中断”握手

处理信号与作业控制:Ctrl-C 不会把 Shell 自己送走;Ctrl-Z 能停住前台任务;支持 fg/bg/jobs。

第五阶段 (MVP 5) · 打磨成工具,而不是玩具

在可用基础上做“顺手/可维护/出错不含糊”:更清晰的错误路径、日志、测试策略与重构。

第六阶段 (MVP 6) · 8 种设计模式重构

功能跑通后再做架构:命令/组合/解释器/访问者/策略/状态/适配器/外观 + RAII,把代码变成“工程”。

Who Is This For

适合人群

  • 正在学习 OS / Unix 系统编程,希望把进程、文件、信号、作业控制串成一个“能跑起来”的综合实验的人。
  • 做 C/C++ 工程但对 fork/exec/pipe/signal 只是“见过”,想补齐可迁移的系统能力的人。
  • 准备面试系统/后端岗位,希望用一个 mini-shell 项目做硬核作品集的人。
  • 喜欢造轮子,希望把日常终端命令背后的机制亲手复现一次的人。

Deliverables

交付物与资产

  • 一个可运行的 mini-shell(prompt + 外部命令 + 管道/重定向 + 信号与作业控制基础)。
  • tokenizer/parser 的单元测试与一组可复现的执行集成测试脚本。
  • 一份“为什么这样实现”的设计复盘:进程组、终端控制权、信号策略等关键点。
  • 一段可直接写进简历的项目描述与面试问答要点。

Resume-Ready

简历怎么写(可直接复制)

一句话版本

建议放在:项目经历 / 亮点
用 C++ 从零实现 mini-shell(POSIX):支持外部命令执行、管道/重定向、信号与作业控制(fg/bg/jobs),并以单元测试/集成测试验证 tokenizer/parser 与执行行为。

完整简历示例(三种风格)

版本 A · 偏技术深度

mini-shell(C++ / POSIX)

  • • 设计并实现递归下降 parser,将命令行输入构建为 AST;支持引号/转义、环境变量展开与 glob 通配
  • • 基于 fork/exec/wait 实现进程生命周期管理,正确处理僵尸进程回收与错误码传递
  • • 实现多级管道与重定向(> / < / 2> / >> / |):用 close/dup2 完成 FD 接线,无泄漏
  • • 实现作业控制:进程组 + tcsetpgrp 切换终端控制权,支持 Ctrl-C/Ctrl-Z 与 jobs/fg/bg
  • • 单元测试覆盖 tokenizer/parser 边界用例 50+;集成测试脚本覆盖 25 组典型命令组合
  • • 用命令/组合模式统一命令执行模型;访问者模式解耦 AST 遍历与执行逻辑

版本 B · 偏工程实践

mini-shell(C++ / POSIX)

  • • 从零实现 POSIX 兼容的交互式 shell,支持外部命令、管道、重定向与作业控制
  • • 采用模块化架构:tokenizer → parser → executor 解耦,便于单元测试与后续扩展
  • • 编写 50+ 单元测试验证解析边界;20+ 集成脚本覆盖 pipeline、重定向、信号等场景
  • • 实现 FD 生命周期追踪与泄漏检测;错误路径统一处理,提供清晰的用户提示
  • • README 提供一键构建与 5 条验证脚本,支持 CI 集成
  • • 设计模式重构:策略模式抽象 PATH 查找;适配器/外观模式封装系统调用,支持 mock 测试

版本 C · 偏学习成长

mini-shell(C++ / POSIX)

  • • 系统学习 POSIX 进程模型(fork/exec/wait)与文件描述符机制,并通过项目实践落地
  • • 独立实现 tokenizer + parser,掌握词法分析与语法树构建的基本方法
  • • 深入理解管道与重定向原理,能清晰解释 close/dup2 的 FD 接线逻辑
  • • 掌握信号与作业控制机制:进程组、终端控制权、前台/后台切换
  • • 建立「先写测试再实现」的工程习惯,单元测试与集成测试覆盖核心路径
  • • 掌握状态模式管理作业状态机;RAII 自动归还 fd/signal mask/终端控制权

以上三个版本侧重点不同,建议根据目标岗位选择或混搭——技术深度、工程能力、学习成长各有侧重,结合你的实际数据调整细节。

面试常见追问

  • 为什么 cd/exit 不能用 fork+exec?
  • 管道两端 close 的顺序有讲究吗?
  • Ctrl-C 打断的是谁?shell 还是子进程?
  • 如何避免僵尸进程?waitpid 的 flags?

简历注意事项

  • 数字要真实:测试用例数、覆盖率等要能自圆其说
  • 准备好 demo:面试官可能要求现场演示
  • README 要清晰:一键构建 + 典型用例
  • 能讲清「为什么这样设计」比「做了什么」更重要

技术栈一览

  • 语言:C++17 / 现代风格
  • 系统调用:fork / exec / wait / pipe / dup2
  • 信号处理:sigaction / tcsetpgrp
  • 测试:单元测试 + 集成脚本
  • 设计模式:命令 / 访问者 / 策略 / 状态 / RAII

Interview Talk Track

面试怎么展开讲(你可以照着讲)

为什么 cd/exit 不能用 exec?

解释“builtin 必须在父进程修改状态”:cd 改变当前进程工作目录;exit 结束 shell 本身。

fork/exec/wait 的关键语义是什么?

为什么 fork 后父子都往下走;exec 成功后为何不会返回;如何用 wait/waitpid 回收子进程避免僵尸。

管道为什么是一串 close/dup2?

描述每个进程应关闭哪些端以避免阻塞;为什么必须关掉未使用的 pipe fd;如何串联多级 pipeline。

Ctrl-C/Ctrl-Z 打断的是谁?

讲清楚前台进程组与信号投递:shell 自己如何忽略/转发信号;fg/bg 如何切换终端控制权。

Make It Quantified

让简历更有杀伤力:量化与复现模板

把“支持了什么”变成清单:外部命令、引号/转义、重定向、pipeline、jobs/fg/bg、错误码与提示等。

把“可靠性”写出来:你写了多少 tokenizer/parser 单测、多少条集成脚本(把数字填进去会非常加分)。

把“难点决策”写出来:进程组/终端控制权/信号策略、FD 生命周期管理、错误处理与回收策略。

附上可复现方式:README 给出 3–5 条一键脚本用例(例如带管道与重定向的组合命令)。

Syllabus

章节目录

Ch 01

为什么要自己写 Shell?

01-why-build-shell.md

Ch 02

创世纪:一个最小 REPL(prompt + read + run)

02-genesis-min-repl.md

Ch 03

进程模型速成:fork/exec/wait 的三件套(先跑通绝对路径:/bin/ls)

03-process-model-fork-exec-wait.md

Ch 04

Tokenizer:把一行命令切成 token

04-tokenizer.md

Ch 05

Parser:从 token 到 AST(先支持“简单命令”)

05-parser-ast.md

Ch 06

命令查找(PATH):把 execvp 的黑盒掀开

06-path-and-execve.md

Ch 07

Builtins I:cd / exit / pwd(为什么它们不能用 exec)

07-builtins-cd-exit-pwd.md

Ch 08

引号与转义:让 echo "a b" 正常工作

08-quotes-and-escape.md

Ch 09

环境变量与展开:$PATH、$HOME、最小 glob(可选)

09-env-and-expansion.md

Ch 10

重定向:> < 2> 的文件描述符接线

10-redirection.md

Ch 11

| 的本质是一串 close/dup2

11-pipeline.md

Ch 12

Signals:Ctrl-C 打断的是谁?(为作业控制铺路)

12-signals.md

Ch 13

作业控制 I:前台/后台与进程组 (process group)

13-job-control-process-group.md

Ch 14

作业控制 II:jobs/fg/bg 与终端控制权

14-job-control-fg-bg-jobs.md

Ch 15

行编辑与历史:把交互做“顺手”(最小实现,可选加餐)

15-line-editing-history.md

Ch 16

重构与测试策略:让 Shell 可维护

16-refactor-and-tests.md

Ch 17

总结与下一步:从 Shell 走向 OS / 编译原理 / 容器

17-summary-next-steps.md

Ch 18

设计模式重构 I:命令与语法树(命令 + 组合/解释器模式)

18-design-pattern-command-composite.md

Ch 19

设计模式重构 II:解耦执行与规则(访问者 + 策略模式)

19-design-pattern-visitor-strategy.md

Ch 20

设计模式重构 III:作业控制与资源归还(状态模式 + RAII)

20-design-pattern-state-raii.md

Ch 21

设计模式重构 IV:系统调用封装与可测试性(适配器 + 外观模式)

21-design-pattern-adapter-facade.md

Scope

本课程的“边界”

不追求 bash/zsh 的完整兼容;追求每一小步都能验证、能解释、能复现。

以 POSIX/类 Unix(macOS/Linux)作为统一基线;Windows 也可通过 WSL / 容器 / 虚拟机等方式完成全部实践。

容易拖进深坑的特性会标为可选挑战:完整 glob、子 shell、脚本语言、补全等。

Next Step

想要课程大纲、价格或开班时间?

扫描右侧二维码添加微信,备注「shell」,获取 mini-shell 课程大纲、价格与开班时间。

微信二维码

微信扫码添加 · 备注「shell」