コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
Linux / macOS / Windows のアーキ比較
手元で動いたスクリプトが、同僚の環境で落ちる
Data/Users.csv を読むスクリプトが、自分の Mac では動くのに、同僚の Linux で「そんなファイルは無い」と落ちる。実体は data/users.csv で、Mac が大文字と小文字を区別しない設定だっただけ、というのはよくある事故です。Windows へ持っていけば、今度はパスの区切り文字で転びます。
システムコールの窓口はどの OS にもあります。ただし窓口の数も、名前も、置き場所の作法も揃っていません。3 つの OS の違いは好みの問題ではなく、それぞれのカーネルが別の出自を持っていることから来ています。
| OS | カーネル | 出自 | パス区切り | 大文字と小文字 |
|---|---|---|---|---|
| Linux | Linux | UNIX を手本に書き直し | / | 区別する |
| macOS | XNU | Mach と BSD の混成 | / | 既定では区別しない |
| Windows | NT | VMS の流れをくむ独自系 | \ と / | 区別しない |
Linux と macOS はどちらも POSIX という共通の作法に沿うので、書き方がよく似ています。macOS は公式に UNIX の認証を受けており、UNIX ではないというのは誤解です。Windows NT は UNIX とは独立して設計されたので、似ているところのほうが少なくなります。
カーネルの中の作りにも差があります。Linux はファイルシステムもネットワークもドライバも、全部をカーネルの中に置く一枚岩の構成です。速い代わりに、中の 1 か所が壊れると全体に波及します。macOS の XNU は、最小限だけを核に残して他を外に出す設計と、UNIX 由来の一枚岩を混ぜた形をとっています。Windows NT は機種依存を吸収する層を 1 枚挟み、その上に複数の作法を同居させます。Windows で Linux のコマンドが動くのは、この同居のしくみが今も生きているからです。
プロセスの作り方からして違う
出自の違いがいちばんはっきり出るのが、新しいプログラムを起動するときです。
POSIX 系では、まず自分自身を丸ごと複製し、複製したほうの中身を目的のプログラムに入れ替えます。複製と入れ替えの 2 段構えです。一方 Windows では、起動したいプログラムの場所を渡して 1 回呼ぶと、新しいプロセスができあがります。
c
pid_t pid = fork(); // 自分を複製する
if (pid == 0) {
execve("/bin/ls", argv, environ); // 複製した側を ls に入れ替える
}2 段構えは回りくどく見えますが、複製したあと入れ替えるまでの間に、開くファイルや権限を細かく調整できるという利点があります。シェルのリダイレクトはここを使っています。逆に Windows のやり方は、渡す引数が増える代わりに 1 回で済みます。
配り方も、それぞれの都合で分かれた
アプリの入れ方の違いも同じ根から来ています。Linux は依存関係を OS 側が解決する仕組みを持ち、apt や dnf が必要なライブラリごと引き連れてきます。macOS は必要なものをアプリの中に全部入れて 1 つのかたまりとして配ります。Windows はインストーラが自分で面倒を見る文化が長く続きました。
どれが優れているかという話ではありません。手元の OS がどの系譜にいるかを知っていると、動かなかったときに疑う場所が絞れます。まずは uname -a で、自分が今どこに立っているかを確かめてください。