
Application 层:很多命令名字,
其实是“历史遗留缩写”
ls —— 为什么不是 list
ls = list segments / list directory 同时代的还有:cp、mv、rm
影响至今:
Linux 命令“短而怪”,但组合能力极强 这是 UNIX 哲学的第一代烙印:少打字,多组合
80列、矩形孔的标准的IBM打孔卡片,已经打孔表示了字符集。此类型用于存储数据。
grep —— 真的是从“正则表达式”里来的
全称来自早期编辑器 ed 的命令: g/re/p
global
regular expression
print 后来被独立做成一个程序,就叫 grep,所以: ps aux | grep ssh 本质上是在做 “全局正则打印”
egrep / fgrep 曾经存在 GNU 后来统一为 grep -E / -F
vi / vim —— “不是为了新手设计的”
vi = visual editor
h j k l 用来移动 模式化(normal / insert)是为了 减少按键数
vim = Vi IMproved,90 年代 Bram Moolenaar 扩展,但仍然保留向后兼容
这也是为什么:
vi 学习曲线陡
但熟练后效率极高
今天还能在 initramfs、救援系统里用
tar —— 真的是“磁带时代产物”
tar = tape archive
原始用途:把文件顺序写入 磁带,所以:
没有随机访问,不能“删除某个文件再压缩”
为什么参数看起来反人类?
tar xvf file.tar 因为最早 没有 - 这也是为什么 tar + gzip 是两步: tar cf - dir | gzip > dir.tar.gz
学生时代风靡校园的磁带机
System Call 层:命令“消失了”,只剩下动词
fork —— UNIX 最天才也最怪的设计
fork():复制当前进程,返回两次(父进程 / 子进程)
历史原因:UNIX 作者不想设计复杂的“进程创建 API” , 结果:
pid = fork(); if (pid == 0) { execve(...); }
优点:
代价:
初学者完全看不懂
Windows 至今没有真正的 fork
execve —— 为什么不叫 run
exec = execute
特点:不创建新进程,直接“替换当前进程映像”
所以 shell:先 fork,子进程 exec
这也是为什么: ps 看不到 shell 调用过的命令进程残留
fork + exec 是 Linux 进程模型的核心信仰
ioctl —— 工程师最后的“垃圾桶”
ioctl = I/O control
设计初衷: 给驱动一个“兜底接口” 现实:
后果:
你在驱动里看到的:
_IOR('V', 1, struct xxx) 基本都是 ioctl
Kernel 层:为什么“看不到 command”
内核层“没有 command”是刻意设计
Kernel 不提供:
只提供:
好处:
所以:
ps 实际是 读 /proc
ls 是 readdir() + stat()
一个“串起来”的真实故事
当你敲:ls | grep txt
实际发生的是:
shell fork
子进程 execve(ls)
ls:
open(".")
getdents()
输出写入 pipe
grep 再 fork + exec
grep 调用 read
内核调度、复制数据、返回用户态
这一整套机制,50 年来几乎没变。
参考文献
CTR census machine - 打孔卡 - 维基百科,自由的百科全书