流(stream)和 Shell(外壳)本质是同一个思想在两个不同层次的投影。
一句话本质
Shell = 用户 ↔ 操作系统 的抽象中介
流(Stream)= 程序 ↔ 外部设备 的抽象中介
完全是同构设计。
1. Shell 出现前的世界
用户要直接跟操作系统内核打交道:
- 输机器指令
- 调系统调用号
- 记寄存器、记地址人被机器折磨,效率极低,不可用。
于是出现 Shell:
- 把复杂内核操作包装成简单命令
- 用户不用懂内核,只懂命令
- 统一界面:ls、cp、rm…
2. Stream 出现前的世界
程序要直接跟各种硬件打交道:
- 每种设备一套接口
- 记控制字、记格式、记中断程序被设备折磨,不可移植。
于是出现 Stream:
- 把复杂设备 I/O 包装成字节流
- 程序不用懂设备,只懂读写流
- 统一界面:fopen、fread、fwrite…
Stream的诞生
语言 “流”(stream)的概念并非凭空产生,而是 Unix 操作系统哲学与 C 语言设计目标深度结合的产物,核心是为了解决早期 I/O 操作的设备依赖性与接口混乱问题。下面从历史背景、技术痛点、诞生过程、标准化定型四个阶段,完整讲述它的 “诞生故事”。
一、史前时代:没有 “流” 的黑暗年代(1960s)
在 C 语言与 Unix 出现之前,计算机 I/O 操作极其繁琐、混乱:
-
设备强绑定
- 每种外部设备(读卡机、磁带、磁盘、打印机、终端)都有专属指令、专属寄存器、专属控制逻辑。
- 程序要读键盘、写屏幕、读文件,必须写完全不同的代码,换一台机器或换一种设备,代码几乎要重写。
-
数据格式割裂
- 早期系统强制使用固定长度记录(如 80 列卡片、块读写),不支持连续字节流。
- 程序必须关心:是 “按记录读” 还是 “按字符读”、设备是否缓冲、结束标志是什么。
-
无统一抽象
- 没有 “输入 / 输出” 的通用接口:每个操作系统、每种语言各搞一套 I/O 函数。
- 程序员被淹没在硬件细节中,无法专注业务逻辑。
当时的痛点一句话总结:
设备太多、接口太乱、移植太难、写 I/O 比写业务还累。
二、Unix 的革命:“一切皆文件” 与流的雏形(1970–1973)
C 语言与 Unix 是孪生兄弟—— 由 Ken Thompson、Dennis Ritchie 等人在贝尔实验室同期设计。为了让 Unix 简洁、可移植,他们提出了两个颠覆性思想:
1. 一切皆文件(Everything is a file)
- 把键盘、屏幕、磁盘、串口、打印机、网络……全部抽象成 “文件”。
- 程序读写任何设备,都用同一套系统调用:
open/read/write/close。 - 设备差异被内核驱动隐藏,用户程序只看到 “字节序列”。
2. 流(Stream)的原始定义
Unix 正式提出:
I/O 就是字节的流动(stream of bytes):有序、连续、以 EOF 结束。
- 不管读键盘还是读文件:都是顺序读字节。
- 不管写屏幕还是写磁盘:都是顺序写字节。
- 程序不需要知道背后是啥设备。
这是 “流” 思想的源头:用统一的字节流模型,消灭设备差异。
三、C 语言 stdio 的诞生:从系统调用到标准库(1972–1978)
Unix 的 read/write 是系统调用(内核接口),直接用有两个问题:
- 每次调用都进内核,频繁字符 I/O 极慢。
- 接口偏底层,没有缓冲、格式化(
printf/scanf)、错误处理等高级功能。
于是贝尔实验室的 Mike Lesk 在 1970 年代初开发了一套 portable I/O package(可移植 I/O 库):
- 封装 Unix 系统调用
- 加入用户态缓冲(提高小 I/O 性能)
- 提供
getchar/putchar/printf/scanf/fopen/fclose等高层接口 - 核心抽象:FILE 结构体代表 “流”
这套库后来成为 C 标准 <stdio.h> 的前身。
C 语言 “流” 的正式定义
在 C 中:
流(stream)是程序与数据来源 / 目的地之间的 逻辑通道,以 FILE 表示*,屏蔽设备细节,只提供字节序列读写。
- 输入流:数据从外部 → 程序。
- 输出流:数据从程序 → 外部。
- 标准流(程序启动自动打开):
stdin(标准输入,默认键盘)stdout(标准输出,默认屏幕)stderr(标准错误,默认屏幕)
到 1978 年 K&R《C 程序设计语言》 出版时,stdio.h 与流模型已成为 C 的标准 I/O 范式。
四、标准化与定型:ANSI C(1983–1989)
1980 年代 C 泛滥,各家编译器 I/O 库不兼容。ANSI X3J11 委员会标准化 C 时:
- 正式将 stream 模型、FILE、stdio.h 函数族、标准流 写入 C89 标准。
- 明确:
- 流是字节序列抽象。
- 支持文本流 / 二进制流两种模式。
- 缓冲机制(全缓冲、行缓冲、无缓冲)标准化。
从此,“流” 成为 C 语言不可分割的一部分,并被 C++、Java、Python、PHP 等几乎所有后续语言继承。
五、一句话总结:流为什么会出现?
流 = 为了解决设备混乱而发明的 “统一接口”。
- 历史动力:早期 I/O 设备绑定、接口分裂、无法移植。
- 思想源头:Unix 一切皆文件 + 字节流抽象。
- 技术落地:Mike Lesk 的 portable I/O 库 → C stdio。
- 历史意义:第一次让高级语言实现 “设备无关 I/O”,奠定现代 I/O 模型基础。
简单说:
没有流,C 语言就没法跨设备、跨平台;没有流,现代编程语言的 I/O 设计会晚很多年。
Shell的诞生
一、史前时代:没有 Shell 的世界(1960s)
1. 背景:大型机、批处理、没有 “交互”
- 计算机是 房间那么大的大型机(IBM 7094、DEC PDP 系列)
- 没有个人电脑,多人共用一台机器
- 没有 “命令行”,没有 “敲命令”
- 用户使用方式:批处理(Batch Processing)
2. 批处理有多痛苦?
你想运行程序:
- 把程序写在 穿孔卡片 / 纸带 上
- 交给机房管理员
- 排队几小时~几天
- 机器一次性跑完一批任务
- 打印出结果,再去取纸
- 完全不能交互
- 错一个字符 → 整批作废,重排
- 人被机器奴役
3. Multics:最早的 “交互式” 萌芽(1964–1965)
贝尔实验室、MIT、GE 合作搞 Multics(分时操作系统)
- 第一次实现 多人同时在线、终端交互
- 提出 Shell 概念(Louis Pouzin 命名)
- 做了第一个 命令解释器(Glenda Schroeder 实现)
- 叫 RUNCOM(run command)→ 后来
.bashrc、.vimrc的rc就来自这里
但 Multics 太复杂、太慢、太昂贵贝尔实验室后来 退出 Multics,Ken Thompson、Dennis Ritchie 很不爽
二、导火索:Ken Thompson 的小机器(1969)
1. 一台被遗弃的 PDP-7
- 贝尔实验室有台没人用的 PDP-7(小型机)
- Ken Thompson 想在上面玩自己写的游戏 Space Travel(太空旅行)
- 但 PDP-7 没有操作系统,没法方便地运行程序
2. 他偷偷写了个 “小系统”——UNIX 诞生
1969 年夏天,Ken Thompson 在 PDP-7 上:
- 写了 文件系统
- 写了 进程管理
- 写了 基本系统调用→ 这就是 最早的 UNIX(Uniplexed Information and Computing Service)
3. 但有个致命问题:用户怎么用它?
当时 UNIX 只有内核,没有界面想运行程序:
- 必须 手写汇编调用系统调用
- 必须 懂寄存器、调用号、陷入指令
- 普通人根本用不了
- 只有 Ken、Dennis 等少数极客能用
痛点到了极限:必须做一个 “中间人”。
三、1971:第一个 Shell —— Thompson Shell(sh)
1. Ken Thompson 写了个 900 行的小程序
- 语言:PDP-11 汇编
- 代码:不到 900 行(极简主义)
- 文件名:/bin/sh
- 这就是 人类第一个真正意义上的 Unix Shell
2. 它到底做了什么?(革命性的三点)
(1)把 “系统调用” 翻译成 “人话命令”
以前:
; 汇编:读文件(伪代码)
mov r0, #3 ; 系统调用号 open
mov r1, #file
trap 0
有了Shell
cat file.txt
一行命令 = 几十行底层操作
(2)统一界面:不管内核怎么变,命令不变
- 用户 不用懂内核
- 换机器、换系统 → 命令不变
- 普通人也能用计算机
(3)发明了管道(Pipe)—— 神来之笔
ls | grep txt | wc -l
- 把程序输出直接连到另一个程序输入
- 小工具组合 = 强大功能
- 这是 UNIX 哲学的核心:Do one thing, do it well
3. Thompson Shell 的局限(很原始)
- 没有 shell 变量
- 没有 控制流(if/else/loop)
- 没有 脚本编程
- 只能交互,不能写复杂自动化
但它已经彻底改变了人与计算机的关系。
四、Shell 诞生的真正意义
1. 它是 第一个成功的 “抽象中介”
- 把 复杂多变的内核 藏起来
- 给用户 简单稳定的界面
- 这就是 “分层抽象” 思想的第一次大规模胜利
2. 它创造了 “命令行交互范式”
- 人类从此 直接和计算机对话
- 不再是批处理、不再是卡片
- 开启 个人计算时代
3. 它定义了 UNIX 哲学
- 小工具、组合、管道、文本流
- 今天的 Linux、macOS、服务器、云、容器 全都继承这套思想
4. 它和 Stream 是 双胞胎设计
- Shell:用户 ↔ 内核 的抽象
- Stream:程序 ↔ 设备 的抽象
- 同一个思想,两层实现
- 共同构成 UNIX 成功的核心密码
六、一句话记住 Shell 的诞生
1969 年,Ken Thompson 为了能在 PDP-7 上舒服地玩游戏,顺手写了个 900 行的小程序,把人类从批处理的地狱里救了出来,创造了命令行、管道、UNIX 哲学,最终统治了整个计算机世界。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)