yoshikouki

UNIX哲学の系譜

UNIX哲学は一枚岩ではない。 Bell Labsで言語化された原典、GancarzとRaymondによる体系化、そしてPlan 9やWorse is Better、systemd論争のような批判的継承がある。 原典を辿ることで、「Do one thing well」の一言では見えなかった構造が浮かび上がる。

Bell Labsで生まれた原則(1969–1978)

UNIXはKen ThompsonとDennis Ritchieが作った。 だが哲学を言語化したのは別の人間だ。

Doug McIlroy。 パイプの発明者であり、Thompson、Ritchie が所属した Computing Techniques Research Department の部長だった人物だ。 よく知られている「3行のUNIX哲学」は、Raymond が The Art of Unix Programming の中で、McIlroy が1978年に述べた4つの指針と、その後の要約を引いて紹介している。 この記事では入手しやすい導線として TAOUP を入口にするが、その背後には McIlroy78 と A Quarter Century of Unix がある。 TAOUP

  • Write programs that do one thing and do it well.(一つのことをうまくやるプログラムを書け)
  • Write programs to work together.(協調して動くプログラムを書け)
  • Write programs to handle text streams, because that is a universal interface.(テキストストリームを扱え。 それが普遍的インターフェースだから)

この3行の凝縮形は Salus の A Quarter Century of Unix(1994)に由来し、McIlroy の1978年の4項目をさらに煮詰めたものだ。 細部までこの3行だけで尽くせるわけではないが、少なくとも後のGancarzやRaymondの整理が、ここから強く影響を受けていることは確かだ。

これは事後的な言語化である。 先に哲学があって設計したのではない。 ThompsonとRitchieが自分たち開発者にとって快適なプログラミング環境を作ろうとした結果、パターンが浮かび上がり、McIlroyが言葉にした。

そしてもう一つ。 UNIX哲学はPDP-7時代の制約から生まれた実践知として読むこともできる。 メモリは小さく、CPU資源も乏しい。 だから小さく作る圧力が強く、道具を組み合わせる文化が育った。 哲学が先というより、制約の中でうまくやるための作法が先にあり、それが後から言葉になった、と捉えるほうが自然だろう。

だが制約が消えた後も哲学は生き残った。 なぜか。

人間の認知負荷は今も大して変わっていない、と考えられるからだ。 PDP-7のメモリ制約は消えても、複雑なものを理解し保守する人間側のコストは残る。 「一つのことをうまくやれ」は、機械の制約だけでなく、人間の理解可能性への処方箋としても読める。

Bell Labsから外への伝播(1976–1984)

McIlroy が哲学を言語化した前後に、Bell Labs の文化を外の世界に持ち出した人間がいる。 Brian Kernighan だ。

Kernighan & Plauger の『Software Tools』(1976)は、フィルタとパイプで問題を解くスタイルを動くプログラムで示した。 注目すべきは、原著が Ratfor(Fortran の構造化方言)で書かれていること。 1981年には Pascal 版も出版された。 UNIX 哲学的な設計が UNIX に縛られないことを、McIlroy の言語化と同時期に実践で示していた。

Kernighan & Pike の『The UNIX Programming Environment』(1984)は、Bell Labs の内部文化を外部の開発者に向けて書いた決定的なテキストだ。 シェル、フィルタ、パイプ、テキスト処理を、思想としてではなく「こう使う」という実践として伝えた。

この2冊が Bell Labs の暗黙知を「誰でも読める本」に変えた。 次の Gancarz や Raymond の体系化は、この伝播なしには成り立たなかっただろう。

Mike Gancarzによる体系化(1994)

Gancarzは『The UNIX Philosophy』(邦訳『UNIXという考え方』)でUNIX哲学を9つの大定理と10の小定理に体系化した。 日本では最も広く知られているUNIX哲学の入門書だろう。

Gancarzの功績は「プログラマ以外にも伝わる言葉にした」ことだと言えるだろう。 McIlroyの3行は開発者向けだが、Gancarzはより広い読者層に向けて書いた。

ただし、本稿の視点からは限界も見える。

  • 記述的であって規範的ではない:「UNIXはこうなっている」という観察であり、「こうすべき」という論証が弱い
  • トレードオフの議論がない:各原則が衝突するケースへの処方箋がない
  • 1994年時点の知見:Web以前、クラウド以前

Gancarzを読んで「なるほど」と思った人は、次にRaymondを読むと視野が広がる。

Eric S. Raymondによる実践への拡張(2003)

Raymond の The Art of Unix Programming(TAOUP)は、UNIX哲学を17のRuleに拡張し、なぜそうすべきかの論証を加えた。 全文がオンラインで公開されている。

17のRuleのうち、特に重要なものを挙げる。

Rule of Modularity:モジュール性。 シンプルなパーツをきれいなインターフェースでつなげ。

Rule of Clarity:明瞭性。 巧妙さよりも明瞭さを選べ。

Rule of Composition:合成可能性。 他のプログラムとつなげられるように設計せよ。

Rule of Separation:分離。 ポリシーをメカニズムから切り離せ。 インターフェースをエンジンから切り離せ。

Rule of Representation:表現。 知識をデータに畳み込め。 プログラムのロジックは馬鹿でいい。

Rule of Silence:沈黙。 言うべきことがないなら何も言うな。

Rule of Repair:修復。 失敗するなら派手に失敗しろ。 できるだけ早く、できるだけ大きな音で。

Rule of Generation:生成。 手書きのコードよりコード生成を好め。

Gancarzとの決定的な違いは、各原則に「なぜ」が付いていること。 Rule of Representationで言えば、「データに知識を埋め込め」という原則の背景には「データはプログラムのロジックより扱いやすい(Data is more tractable than program logic)」という経験則がある。

UNIX哲学への批判と対抗

UNIX哲学は無批判に受け入れられたわけではない。

Rob Pike「Notes on Programming in C」(1989)

Bell Labs の系譜に連なる Rob Pike は、データ構造の重要性を強調した。 Notes on Programming in C

Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. (データが支配する。 正しいデータ構造を選び、うまく組織化すれば、アルゴリズムはほぼ常に自明になる。)

Gancarzが「プログラムの小ささ」を強調したのに対し、Pikeは「データ構造の正しさ」を強調した。 どちらもUNIXの伝統の内にあるが、力点が違う。

Plan 9(1992)

Thompson、Pike らが「UNIXの反省を踏まえて作り直したOS」。 Plan 9 の論文では、資源を階層的ファイルとして扱い、9P という共通プロトコルでアクセスし、個々のプロセスが私的な名前空間を組み立てる設計が説明されている。 ネットワーク、プロセス、グラフィックスまでファイルシステム的な発想で統一しようとした点が重要だ。 Plan 9 from Bell Labs

UNIX哲学の自己批判的な進化形。 商業的には大きく広がらなかったが、「あらゆる資源をファイルとして扱う」発想はその後のシステム設計に痕跡を残している。 Linux の FUSE や WSL2 での 9P プロトコル採用はその例だ。

Plan 9が示したのは、UNIX哲学は「UNIXに固有の文化」ではなく「設計原則のセット」であり、UNIX自身を超えて適用できるということ。

Tanenbaum–Torvalds 論争(1992)

1992年1月、comp.os.minix で Andrew S. Tanenbaum が「LINUX is obsolete」と題した投稿を行った。 Tanenbaum は教育用 OS、MINIX の作者であり、オペレーティングシステムの教科書で知られる研究者だ。 LINUX is obsolete

論点はカーネル設計にあった。 モノリシックカーネル(全体が一つのアドレス空間で動く)は1970年代の設計であり、マイクロカーネルが正しい方向だ、と Tanenbaum は主張した。 マイクロカーネルは最小限のカーネルの上に、ファイルシステムやネットワークを独立したサーバーとして配置する。 「一つのことをうまくやれ」をカーネル設計に適用した発想とも読める。

Torvalds は実用主義で応じた。 Linux は動く。 速い。 人が使っている。 マイクロカーネルの理論的優位性は実装で証明されていない。

結果は歴史が示すとおりだ。 Linux(モノリシック)が広く普及した。 後に触れる Worse is Better の構図がここにもある。 ただし、macOS/iOS の XNU カーネルは Mach マイクロカーネルの系譜にあり、マイクロカーネルの思想が完全に消えたわけではない。

後の systemd 論争と並べると対称性がある。 Tanenbaum–Torvalds では「分離すべき」側が負け、systemd では「統合すべき」側が勝った。 いずれも実用主義が理論的な正しさに先行した事例として読める。

GNU と自由ソフトウェア(1983–)

UNIX 哲学の系譜には、技術設計とは別の次元がある。

1983年、Richard Stallman が GNU プロジェクトを宣言した。 1985年には GNU Manifesto を発表し、Free Software Foundation を設立した。 The GNU Manifesto

Stallman の問いは「どう設計するか」ではなく「誰のために設計するか」だった。 UNIX-like だが自由な OS、つまりソースコードを読め、改変でき、再配布できる OS である。 技術的には UNIX 哲学を継承しつつ、その上にソフトウェアの自由という倫理的規範を載せた。

GNU のツール群(GCC、Emacs、Bash、coreutils)は、後に Linux カーネルと組み合わさり、UNIX 哲学の「小さなツールを組み合わせる」設計思想を自由なライセンスの下で再実装したものとなった。

本稿の主題は設計哲学であり、自由ソフトウェア運動の全体像には立ち入らない。 だが UNIX 哲学の系譜を辿る上で、技術思想に倫理的次元を加えたこの分岐は無視できない。

『The UNIX-Haters Handbook』(1994)

Gancarz が UNIX 哲学を体系化した1994年、同じ年に正反対の本が出た。 Simson Garfinkel、Daniel Weise、Steven Strassmann 編『The UNIX-Haters Handbook』だ。 The UNIX-Haters Handbook

UNIX-HATERS メーリングリストに集まった不満を編纂したもので、ユーザーインターフェース、命名規則、ドキュメントの貧弱さを批判している。 序文を Dennis Ritchie 自身が書いている。 UNIX の共同創造者が批判書に序文を寄せた事実は、UNIX 文化の自己批判的な性格を示しているとも読める。

批判の多くは表層的なユーザビリティの問題だが、根底には「開発者にとって快適な環境」と「すべてのユーザーにとって使いやすい環境」の乖離がある。 McIlroy の3行が開発者目線で書かれていたことを思い出せば、この緊張関係は UNIX 哲学の出自に組み込まれていたとも言える。

Worse is Betterという設計思想

Worse is Better は「1991年に突然出てきた標語」ではない。 Richard P. Gabriel 自身の回想によれば、着想は1989年、講演 Lisp: Good News, Bad News, How to Win Big は1990年、そして抜粋が広く流通したのが1991年だった。 Worse Is Better

二つの設計思想

Gabrielは MIT/Stanford流(The Right Thing)と New Jersey流(Worse is Better、Bell Labsの流儀)を対比した。

The Right Thing:

  • 正しさが最優先。 実装が複雑になっても正しさを犠牲にしない
  • 完全性を重視。 想定されるケースは全てカバーする
  • 一貫性を重視。 例外を許さない

Worse is Better:

  • シンプルさが最優先。 ただし実装のシンプルさがインターフェースのシンプルさに優先する
  • 正しさはシンプルさの次。 少し間違っていても、シンプルなほうが良い
  • 完全性と一貫性はさらに劣後する

複雑さをどこに配置するか

多くの人が「Worse is Better = 雑に作っていい」と解釈する。 本稿ではそう読まない。

Gabrielが言っているのは、複雑さをどこに配置するかの話だ。

The Right Thing: 複雑さを実装側が引き受ける。 ユーザーには美しいインターフェースを見せる。 Worse is Better: 実装をシンプルに保つ。 そのしわ寄せはユーザー側に行く。

直感的な例として、UNIX系でたびたび問題になる「シグナルでシステムコールが中断される」話を考える。

read() の最中にシグナル割り込みが入ったらどうなるか?

  • The Right Thing:割り込み後に自動的に読み込みを再開し、利用者に中断をあまり意識させない。 だが実装側は複雑になる
  • Worse is Better:実装の単純さを優先し、中断や再試行の責任を呼び出し側にも負わせる

ここは厳密には単純化がある。 実際の read(2) の再開可否は UNIX 方言や SA_RESTART の有無で変わり、Linux の signal(7) も「詳細は UNIX 実装ごとに異なる」としている。 signal(7) それでも、「インターフェースの滑らかさより、まず実装と機構の単純さを守る」という直感を説明する比喩としては有効だ。

なぜWorse is Betterが広がるのか

Gabrielの最も鋭い洞察は、ソフトウェアの普及をウイルスの伝播に喩えたことだ。

  1. 実装がシンプル → 初期バージョンを早く出せる
  2. 早く出せる → 多くの環境に移植できる
  3. 多く移植される → ユーザーが増える
  4. ユーザーが増える → フィードバックが増える
  5. フィードバックが増える → 改良が進む
  6. 最終的に「ほぼ正しい」ところまで到達する

一方、The Right Thingは正しく作ろうとするほど開発が遅れ、リリースが遅れ、その間にWorseが生態系を制覇している。

C vs Lisp。 UNIX vs Multics。 TCP/IP vs OSIモデル。 いずれもこのパターンで読むことができる。

Gabriel自身の転向

あまり知られていないが、Gabriel自身は何度も立場を揺らしている。

  • 1989年: Lucid での雑談から着想が生まれる
  • 1990年: European Conference on the Practical Application of Lisp で Lisp: Good News, Bad News, How to Win Big を講演する
  • 1991年: 抜粋が広く流通し、Worse is Better という名前で知られるようになる
  • 1991–1992年頃: 「Worse Is Better Is Worse」で自己批判する
  • その後: 「Is Worse Really Better?」で再び擁護に回る
  • 2000年: OOPSLA のパネル準備で再び賛否両論の立場を書き分ける

この振動自体が教訓だ。 設計思想の正否は一意に決まらない。 文脈、時期、スケールで答えが変わる。

Worse is Betterが効く条件

Gabrielのテーゼを構造的に分析すると、効く条件が見えてくる。

効くとき:

  • ユーザーが多様で、完璧な要件定義が不可能
  • 環境が急速に変化し、完成を待てない
  • ネットワーク効果が働く(ユーザー数が価値を決める)
  • 「十分に良い」で実用上問題ない

効かないとき:

  • 失敗コストが極端に高い(航空宇宙、医療、暗号)
  • ユーザーが少数の専門家で、正しさを評価できる
  • 「ほぼ正しい」が「全く使えない」と同義(型システム、証明系)

現代の事例

ここから先は原典そのものではなく、Gabriel の議論を現代の技術史に引き寄せて読むための補助線だ。

Worse is Betterが勝った:

  • JavaScript:言語設計として「正しい」か? だが勝った
  • REST over SOAP:正しさではSOAPが上。 だがシンプルさでRESTが勝った

The Right Thingが勝った(稀):

  • Rust:メモリ安全性の「正しさ」がCのWorse is Betterを凌駕しつつある。 ただし普及に10年以上かかった
  • HTTPS everywhere:「暗号化しなくても動く」というWorseが、ようやく「全部暗号化する」というRight Thingに負けた

パターンとして、The Right Thingが勝つのはWorseの「十分に良い」が崩壊する外圧がかかったとき。 セキュリティ事故、大規模障害、規制。

systemd論争で衝突した原則

UNIX哲学が最も激しく現実と衝突した事例がsystemd論争だ。

何が起きたか

2010年、Lennart Poettering らが systemd を Linux の init system(PID 1 を含むサービス管理機構)として提案した。 それまでの SysVinit はシェルスクリプトの集合体でサービスを順番に起動する仕組みだった。 テキスト、小さなツールの組み合わせ、透明性。 少なくとも理想像としては UNIX 哲学の体現に近い。

systemd はこれを、依存関係管理や cgroups 連携を備えた新しい基盤に置き換えた。 議論の対象は PID 1 単体ではなく、journaldnetworkdresolved など周辺コンポーネントを含む systemd プロジェクト全体へ広がっていった。 systemd 自身も「core components」と「other components」から成ることを明示している。 Minimal Builds

反対派の論点

「一つのことをうまくやれ」の違反。 批判の矛先は「PID 1 が全部やっている」というより、systemd プロジェクトがログ、ネットワーク、DNS など周辺責務まで強く取り込み、従来は独立していた道具の境界を再定義していった点に向いた。

テキストストリームからの距離。 systemd-journald は構造化、索引付きのジャーナルを採用し、journalctl で読む前提の世界観を作った。 systemd-journald.service journalctl はテキスト風の short 出力や JSON 出力も持つので「読めない」は言いすぎだが、/var/log/syslog を素朴に cat して grep する文化から距離を置いたのは確かだ。 journalctl

透明性の喪失。 SysVinit のスクリプトは bash が読めれば追えることが多かった。 systemd は unit ファイル自体は宣言的で読みやすい一方、実行時の振る舞いは内部状態機械や周辺コンポーネントへの理解を要求し、見通しの悪さを感じる人が増えた。

障害の集中。 PID 1 周辺の複雑化は、故障時の影響範囲が大きいという不安を招いた。 とくに「ブートの中枢と周辺機能が密結合していく」こと自体を、設計上の危険信号とみなす見方があった。

賛成派の論点

SysVinitは壊れていた。 シェルスクリプトの起動順序は手動管理で、依存関係が複雑化すると破綻する。 並列起動ができず起動が遅い。 プロセスが死んでも検知できない。

「小さなツールの組み合わせ」は理想論だった。 SysVinitの「シンプルさ」は複雑さをシェルスクリプトに押し付けていただけではないか。 /etc/init.d/ のスクリプトを読んだことがあるなら分かる。 数百行のbashで状態遷移を手書きしている。

宣言的記述はむしろ明瞭。 systemdのunitファイルは意図が明確だ。

[Service]
ExecStart=/usr/bin/myapp
Restart=on-failure

シェルスクリプトの手続き的記述より、何がほしいかが一目でわかる。 Rule of Clarity(明瞭性の原則)に適合するとも言える。

統合による信頼性。 個別ツールの組み合わせは、接着部分にバグや運用負債が潜む。 cgroups との統合で一貫したリソース管理が可能になり、現代的な Linux 運用の基盤として支持された。

原則を適用する粒度

ここが最も重要な点だ。

両陣営ともUNIX哲学を根拠にしている。

  • 反対派:「一つのことをうまくやれ」→ systemdは肥大化している
  • 賛成派:「一つのことをうまくやれ」→ systemdは「システム管理」という一つのことをやっている。 粒度の問題だ

同じ原則から正反対の結論が出る。 これは原則が間違っているのではなく、原則の適用にはコンテキストが必要だということを意味する。

Gancarzが書かなかったのはまさにここだ。 「一つのこと」の粒度をどう決めるか。 ls は一つのことか? git は? systemd は? 答えは設計者が責務をどう切るかに依存する。 原則だけでは決められない。

Worse is Betterの視点

SysVinitは「十分にシンプル」だが「正しくない」(状態管理の欠如、並列起動の不在)。 systemdは「より正しい」が「シンプルではない」。

UNIX の歴史を「常に Worse is Better が勝った」と単純化するのは危うい。 それでも systemd 論争は、小さく分かれた道具よりも、統合された管理基盤が支持を広げたケースとして読むことができる。

なぜか。 制約が変わったから。 サーバーの台数が数台から数千台になり、コンテナが標準になり、「手書きシェルスクリプトで管理する」がスケールしなくなった。 Worseが「十分」でなくなった瞬間、Betterが勝つ。

2026年現在、主要 Linux ディストリビューションの多くが systemd を採用している。 一方で、Void Linux(runit)や Devuan(systemd を採らない Debian 系)など、別の哲学を維持しようとする流れも残っている。

現代への射程

UNIX 哲学の影響は systemd 論争で止まらない。

コンテナとマイクロサービス

Docker(2013)に始まるコンテナ化は、「一つのことをうまくやれ」をプロセスからサービスへ拡張した動きとして読める。 一つのコンテナに一つの責務を持たせ、サービス間は API で通信する。 パイプが HTTP に、テキストストリームが JSON に変わったと見ることもできるだろう。

ただし、マイクロサービスが「UNIX 哲学の正統な後継」かは議論の余地がある。 分散システムの複雑さは、パイプで繋がる小さなツール群のシンプルさとは質的に異なる。 「小さく分ける」という原則を適用しても、ネットワーク越しの結合がもたらす障害モードは、プロセス間パイプとは別種の難しさを持つ。

PowerShellが流す構造化オブジェクト

Microsoft の PowerShell(2006)は、Jeffrey Snover が設計したシェルだ。 パイプラインの概念は UNIX から受け継いだが、テキストではなく .NET の構造化オブジェクトをパイプで流す設計を選んだ。

McIlroy の「テキストストリームが普遍的インターフェース」への直接的な対抗提案だ。 テキストは柔軟だが awksed でパースする脆さがある。 構造化オブジェクトは型安全だが、「何でもテキスト」の気軽さを失う。 どちらが優れているかではなく、何を普遍的インターフェースとするかという設計判断の違いがここにある。

現代 CLI ルネサンス

2010年代以降、UNIX 哲学に忠実な新世代の CLI ツールが登場している。 jq(2012、JSON フィルタ)、ripgrep(2016、高速 grep)、fd(2017、高速 find)。 いずれも「一つのことをうまくやる」小さなツールだが、速度、Unicode 対応、構造化データなど現代の要求に応えている。

少なくとも CLI の世界では、これらのツールが UNIX 哲学を受け継いでいる。 コマンドラインという文脈の中で、パイプとフィルタの思想は今も生きている。

哲学はレンズである

ここまで辿ってきて見えることがある。

UNIX哲学は教条ではなく、設計を鍛えるレンズだ。

「この設計はUNIX哲学に反するか?」という問い自体が設計を鍛える。 答えが「反する、でもやる」であっても構わない。 問いを通過したことに価値がある、と筆者は考える。 通過しなかった設計と、通過した上で逸脱した設計では、品質が違うはずだ。

原則間の衝突(シンプルさ vs 完全性、小ささ vs ユーザビリティ)は解消するものではなく、設計判断として引き受けるものだ。

そしてUNIX哲学の根底にある「人間が扱える複雑さには限りがある」という洞察は、制約が変わっても、ツールが変わっても、有効であり続ける。

参考文献