学径XUEJING · 个人学习平台通知设置

课程库 技术雷达 程序的三张脸 › 第 1

CLI · TUI · GUI —— 程序跟人打交道的三张脸

普通课35 分钟

本课导读

这三个缩写描述的是同一个问题的三种答案:程序怎么跟人交互。你其实三种全都天天在用——npm run dev 是 CLI,Claude Code 是 TUI,VS Code 是 GUI——只是没人把这张地图摊开给你看过。本课把三张脸各自的解剖结构、为什么最古老的 CLI 至今统治开发者世界、以及"桌面应用为什么都是 Electron"讲清楚。预计 35 分钟。

三张脸一览

CLITUIGUI
全称Command-Line Interface 命令行界面Text-based UI 终端文本界面Graphical UI 图形界面
交互方式敲一条命令 → 输出文字 → 结束终端里用字符"画"出的持续界面窗口、按钮、鼠标
你用过的git、npm、claude 命令本身Claude Code 的对话界面、htopVS Code、浏览器、微信
诞生年代1960s1980s1980s

解剖 CLI:一条命令的五脏六腑

拿一条你敲过无数遍的命令开刀:

npm  install  --save-dev  eslint
 │      │         │          │
程序   子命令    选项(flag)   参数
  • 程序npm 是一个可执行文件,操作系统按 PATH 环境变量里列出的目录顺序找到它
  • 子命令/参数:告诉程序做什么、对谁做
  • 选项(flag)--xxx 长写法、-x 短写法,调整行为细节

程序运行完还会留下三样东西,这是 CLI 世界的"社交协议":

  • 标准输出(stdout):正常结果往这打
  • 标准错误(stderr):报错和日志往这打(跟 stdout 分开,所以"结果"能被干净地存下来而不混进报错)
  • 退出码(exit code):0 = 成功,非 0 = 失败。你项目 CI 里"测试挂了就不许部署",判断依据就是测试命令的退出码

CLI 凭什么 60 年不死

答案一个词:可组合(composable)。CLI 程序遵守一个天才约定——我的输出可以变成你的输入,用管道符 | 连接:

Bash
# 管道:把三个各干一件小事的程序串成一条流水线
# 「列出进程 → 筛出包含 node 的行 → 数有几行」

# macOS / Linux / Git Bash:
ps aux | grep node | wc -l

# 同样思想的 PowerShell 版(Windows):
# Get-Process | Where-Object { $_.Name -match "node" } | Measure-Object

# 再来一个你能直接用的:找出项目里最大的 5 个文件
# du -ah . | sort -rh | head -n 5

每个小程序只做一件事,但像乐高一样任意拼装——这就是 Unix 哲学。由此衍生出 CLI 的三大不可替代性:

  1. 可脚本化:能敲的命令就能写进脚本自动执行。GUI 里"点这里、再点那里"没法自动化,CLI 天生就是自动化的原料——你项目的 CI/CD、package.json 里的 scripts,全是 CLI 命令的编排
  2. 可远程:服务器没有显示器,SSH 连上去只有终端——运维世界 100% 是 CLI 的
  3. 对机器友好:文本输入文本输出,程序容易调用程序。AI agent 时代这条突然升值——Claude Code 能替你干活,正是因为开发世界的一切都有 CLI 接口可调

提示

所以"学命令行"不是学古董,而是学开发者世界的通用总线。GUI 是给人看的门面,CLI 是程序之间、人与自动化之间的接口。越往工程深处走,CLI 浓度越高。

TUI:终端里长出来的"伪 GUI"

TUI 介于两者之间:还是在终端里、还是纯字符,但不是"一问一答就结束",而是持续运行、可交互的界面——用字符画出边框、列表、进度条,响应你的按键。

你最熟的例子就是 Claude Code 本身:它运行在终端里(CLI 的壳),但有持续的对话界面、彩色面板、快捷键(TUI 的魂)。其他名角:htop(服务器资源监控仪表盘)、lazygit(终端里的 Git 图形操作)、vim

TUI 存在的理由:在只有终端的环境(SSH 远程、纯键盘流)里,提供接近 GUI 的信息密度和交互效率。近年终端工具复兴(开发者回流终端 + AI 工具都长在终端里),TUI 正在小规模文艺复兴。

GUI:图形界面的技术路线之争

GUI 本身你太熟了,值得上雷达的是桌面 GUI 怎么做出来的路线之争——这直接解释"为什么 VS Code 吃内存"这类日经话题:

  • 原生(native):用操作系统自家的 UI 框架(Windows 用 WinUI、macOS 用 SwiftUI)。性能和质感最好,但每个平台要写一遍,成本三倍
  • Electron:把一个完整的 Chrome 浏览器 + Node.js 打包进你的应用,界面用网页技术写。一套代码全平台跑,前端工程师直接上手——VS Code、Slack、Discord、Figma 桌面版全是。代价:每个应用自带一个浏览器,安装包几百 MB、内存几百 MB 起步
  • Tauri:上一课的老朋友 Rust 登场——思路和 Electron 一样"用 Web 技术画界面",但不打包浏览器,复用操作系统自带的 WebView,原生侧用 Rust。安装包能从几百 MB 缩到几 MB。是 Electron 目前最有声量的挑战者

说明

看到没有,雷达上的点开始连线了:Rust(第 1 课)→ Tauri(本课)。零散知识变成网络的瞬间,就是它们开始互相解释的时候。

亲手看一眼 CLI 的原料

一个最小的 Node CLI,看看"命令行参数"到底怎么进入程序的:

TypeScript
#!/usr/bin/env node
// greet.ts —— 一个最小 CLI:读取参数和选项,打印结果,返回退出码

// process.argv = ["node 路径", "脚本路径", ...你敲的参数]
const args = process.argv.slice(2);

if (args.length === 0) {
console.error("用法:greet <名字> [--loud]"); // 报错走 stderr
process.exit(1);                              // 非 0 退出码 = 失败
}

const name = args[0];
const loud = args.includes("--loud");
const msg = loud ? `你好,${name}!!!`.toUpperCase() : `你好,${name}`;

console.log(msg);   // 结果走 stdout
process.exit(0);    // 0 = 成功(不写也默认 0)

// 运行:npx tsx greet.ts 站长 --loud
// 或者用上一课的 Bun:bun greet.ts 站长 --loud

就这么多:参数从 argv 进来,结果从 stdout 出去,成败用退出码表态。npm 上那些著名 CLI(eslint、vite……)的骨架和这 20 行没有本质区别,只是多了参数解析库和漂亮的彩色输出。

够用判断线

一句话总结:CLI 是可组合、可自动化的文字接口(开发世界的总线),TUI 是终端里的持续交互界面,GUI 是给大众的图形门面;桌面 GUI 三条路线 = 原生(贵而精)、Electron(Web 技术 + 自带浏览器,重)、Tauri(Web 技术 + 系统 WebView + Rust,轻)。 值得深入的信号:你想把重复劳动自动化(学 shell 脚本),或想把自己的工具发布给别人用(学写 CLI)。

随堂测验

随堂测验0 / 4 题正确

1. CLI 诞生 60 年仍统治开发者世界,最核心的原因是?

2. 一个 CLI 程序运行结束后退出码是 3,这意味着什么?

3. Claude Code 的界面属于哪一类?为什么?

4. 「VS Code / Slack / Discord 为什么都那么吃内存?」——最准确的回答是:

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…