1973 - Unix 以 C 重寫與管道(可移植性與組合性雙勝利)#
案件摘要#
1973 年,Dennis Ritchie 用 C 語言重寫 Unix(Version 4)——作業系統史上第一次,核心脫離組合語言,變成可移植的系統。 同年 Thompson 發明管道(pipe)——把一個程式的輸出接到另一個的輸入,開啟 Unix 最深遠的發明:組合性。
\[ \text{可移植性(C 重寫)} \;+\; \text{組合性(管道)} \;=\; \text{Unix 征服世界的兩大武器}. \]
前因 -- 為什麼會有這個案子#
- PDP-11 換代與可移植的渴望:每次換機器就要重寫數萬行組語——彌補的缺陷:不可移植。B 語言(Thompson 1969)太快、太無型別、無法表達硬體細節,Ritchie 因此設計 NB→C:有型別、可編譯出高效率程式碼。
- 管道的動機:McIlroy 觀察到大家一直在寫「把 A 的輸出接給 B」的臨時程式——與其在每個程式裡重複寫,不如讓 shell 一次統一支援。
- 理論基礎:管道本質是串流(stream)與協程(coroutine)——生產者與消費者並行、以有限緩衝解耦。
線索與推理 -- 數學式、程式、理論#
第一條線索:C 重寫——「高階語言寫 OS」的證明#
\[ \text{C 程式碼} \;\xrightarrow{\text{PDP-11 編譯器}}\; \text{機器碼} \;\approx\; \text{手寫組語的效率}. \]
- 彌補的缺陷:組語不可移植、不可讀、維護成本高。
- 理論意義:證明 OS 核心可以「機器無關」——只需要為每台新機器重寫一小部分(編譯器 + 少數機器相關檔案)。
- 從此 Unix 從 PDP-11 移到 Interdata 8/32、VAX……一次寫作,處處編譯。
第二條線索:管道——組合的代數#
\[ \text{工具}_1 \;|\; \text{工具}_2 \;|\; \text{工具}_3 \quad\Longrightarrow\quad \text{組合爆炸的生產力}. \]
- 實作:
pipe(fd)產生一對檔案描述子,配合fork,父行程寫入端、子行程讀出端——一切皆檔案的完美應用。 - 哲學(McIlroy 總結):
寫只做一件事但做好的程式;寫能協作的程式;寫能處理文字流的程式,因為那是通用介面。
第三條線索:stdlib 的雛形#
C 重寫同時確立 stdio(printf/fopen)——把 I/O 抽象成字元流,與管道思想同源:文字流是通用介面。
C 範例:管道的系統呼叫本質#
#include <unistd.h>
#include <stdio.h>
int main(void) {
int fd[2];
pipe(fd); /* fd[1] 寫入端, fd[0] 讀出端 */
if (fork() == 0) { /* 子行程:充當「下游工具」 */
dup2(fd[0], 0); /* 把讀出端接到 stdin */
close(fd[1]);
execlp("wc", "wc", "-l", NULL); /* 統計行數 */
}
dup2(fd[1], 1); /* 父行程:把寫入端接到 stdout */
close(fd[0]);
execlp("ls", "ls", NULL); /* 相當於 shell: ls | wc -l */
return 0;
}
Shell 範例:組合性的鐵證#
# 相當於 shell: cat /etc/passwd | cut -d: -f1 | sort | head -5
$ cat /etc/passwd | cut -d: -f1 | sort | head -5
Python 範例:重現 Unix 管道#
import subprocess
p1 = subprocess.Popen(["cat", "/etc/passwd"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["cut", "-d:", "-f1"], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(["sort"], stdin=p2.stdout, stdout=subprocess.PIPE)
out = subprocess.check_output(["head", "-5"], stdin=p3.stdout).decode()
print(out)
結案 -- 後果與影響#
- 可移植性 → Unix 佔領所有機型;C 成為此後 50 年系統軟體通用語言(Linux、Windows 核心、Git 全是 C)。
- 管道 → shell 腳本、資料管道、今天的 DevOps 與
|、|&、xargs全是後裔。 - 1974 年 CACM 論文發表(見
1974-CACM論文與授權擴散.md)。 - 歷史教訓:不是功能多者勝,而是介面統一、可組合者勝。
關鍵人物與文獻#
- D. M. Ritchie:C 語言設計者;〈The Development of the C Language〉(1993)。
- D. McIlroy:管道構想 (1964 早已提出,1973 落實);〈A Research UNIX Reader〉。
- 相關案件:
1969-Unix誕生.md、1974-CACM論文與授權擴散.md。