1 前提
1.1 環境
実行環境は以下のようになっています。
- ホスト OS:Windows 11
- ゲストOS / ディストリビューション:Ubuntu 24.04.4 LTS
- 実行環境:WSL2
- WSL2上で見えているカーネル:Linux 6.6系
- CPU アーキテクチャ:x86_64
- シェル:bash
WSLでUbuntuを動かしている関係上、この記事にはそれ関連の説明が混じっています。
1.2 Everything is a file
Unix系OSには、「すべてファイルとして扱おう」という考え方があります。たとえば、デバイス、端末、プロセス情報、カーネル情報なども、ファイルやディレクトリのように読み書きできる形で表現されることがあります。
ただし、これは設計思想に近い考え方です。実際に、「すべてが通常のテキストファイルとして存在する」と言っているわけではありません。通常ファイル、ディレクトリ、デバイスファイル、シンボリックリンク、ソケットなどを、パス名やファイルディスクリプタを通じて統一的に扱える、という意味に近いです。
1.3 ファイルの区分
ファイルには、「共有可能(Shareable)」と「共有不可(Unshareable)」、「可変(Variable)」と「静的(Static)」にそれぞれ区別することができます。
「共有可能」なファイルである場合、ホストが保存しているものを他から使用できます。「共有不可」の場合、他のホストから共有して使うことを想定していません。
「可変」なファイルである場合、システム管理者の介入なしに変更できます。「静的」の場合、システム管理者の明示的な操作なしには変化しません。
たとえば、/usrは複数のホストで共有できる静的なデータ、/etcはそのマシン固有の静的な設定ファイル、/runはそのマシンの起動中だけ意味を持つ可変データ、というように整理できます。
| 静的(Static) | 可変(Variable) | |
|---|---|---|
| 共有可能(Shareable) |
/usr/opt
|
/var/mail/var/spool/news
|
| 共有不可(Unshareable) |
/etc/boot
|
/run/var/lock
|
2 全体像
とりあえず、ルートディレクトリ直下のディレクトリを見ることにしましょう。
$ ls -a /
. bin.usr-is-merged etc lib lost+found opt run snap tmp
.. boot home lib.usr-is-merged media proc sbin srv usr
bin dev init lib64 mnt root sbin.usr-is-merged sys var
なお、ls -a / に表示される . と .. は通常のディレクトリ名です。
-
.は現在のディレクトリ -
..は親ディレクトリ
を表します。
ディレクトリの役割は、ざっくりこんな感じになっています。(上で出力されたものが一部入っていません。)
/
├── bin 基本コマンド
├── boot 起動関連
├── dev デバイスファイル
├── etc 設定ファイル
├── home 一般ユーザーのホーム
├── lib 共有ライブラリ
├── media 自動マウント先
├── mnt 手動マウント先
├── opt 追加ソフトウェア
├── proc プロセス・カーネル情報
├── root rootユーザーのホーム
├── run 実行中の一時情報
├── sbin 管理者用コマンド
├── srv サービス用データ
├── sys カーネル・デバイス情報
├── tmp 一時ファイル
├── usr 多くのプログラム本体
└── var 変化するデータ
3 ディレクトリ
3.1 bin
binaryの略です。
基本的な実行ファイルが置かれています。
基本的には、/binの中にサブディレクトリを作ってはいけないことになっています。なぜならFHS1が/binを基本コマンドを平らに配置する場所として定義しているためです。
私の環境だとusr mergeによって実体が/usr/binに統合されています。
以下のコマンドで確認できます。
$ ls -ld /bin
/bin -> usr/bin
3.2 bin.usr-is-merged
これは、Ubuntuで/binが/usr/binに統合済みであることを示すための管理用の目印です。
/binが統合された後も残り続けている理由の一つは、互換性です。
例えば#!/bin/bashのように書かれているファイルは大量にあり、/binをなくすとこれらが意味を成さなくなります。ですから、現在でもシンボリックリンクとして残すことで、混乱を避けています。
usr merge
これは、昔は分かれていたディレクトリを統合する流れのことを言います。昔、起動直後や復旧モードでは、/usrがまだマウント2されていない可能性がありました。つまり、/と/usrが別ファイルシステムの場合がありました。その状態で、重要なコマンドを/usr/binに置くわけにはいきません。
しかし、最近は/usr/binに置いても問題なくなってきたので、これを統合する流れとなっています。
3.3 boot
OSの起動に必要なファイルがあります。
筆者の環境だと、WSLによってこのディレクトリに何もファイルがありませんでした。
通常のLinux環境では、/boot にはカーネル本体やブートローダ関連のファイルが置かれます。
たとえば vmlinuz-... は圧縮されたLinuxカーネル、initrd.img-... は起動初期に使われる一時的なルートファイルシステムです。
3.4 dev
deviceの略です。
デバイスを表すファイルが置かれています。
Linuxでは、キーボードや端末などの物理デバイスもファイルのように扱われるという特徴があります。
代表的なものとして、以下のようなファイルがあります。
/dev/null 何を書いても捨てる
/dev/zero 読むと0のバイト列を返す
/dev/tty 現在の端末
/dev/sda ディスクを表すブロックデバイスの例
null
/dev/nullは、何を書き込んでも消えるファイルです。
実際に書き込んで見ても、何も表示されません。
$ echo hello > /dev/null
$ cat /dev/null
3.5 etc
システム全体の設定ファイルが置かれます。
代表的なものとして、以下のようなファイルがあります。
/etc/passwd ユーザー情報
/etc/group グループ情報
/etc/hosts ホスト名とIPアドレスの対応
/etc/fstab ファイルシステムのマウント設定
/etc/apt/ apt の設定
/etc/systemd/ systemd 関連設定
3.6 home
一般ユーザーのホームディレクトリが置かれるディレクトリです。
3.7 init
WSLが用意している初期化プログラムです。
3.8 lib
libraryの略です。
共有ライブラリなどが置かれます。
私の環境だとusr mergeによって実体が/usr/libに統合されています。
$ ls -ld /lib
/lib -> usr/lib
3.9 lib.usr-is-merged
binと同様に、/libは/usr/libに統合されていることを示しています。
3.10 lib64
64bit用ライブラリや、動的リンカに関係するディレクトリです。
3.11 lost+found
ファイルシステムの修復時に使われます。
3.12 media
USB メモリや外付けディスクなどが自動マウントされる場所です。
3.13 mnt
mountの略です。
一時的にファイルシステムをマウントする場所です。
3.14 opt
optionalの略です。
追加でインストールした大きめのアプリケーションなどを置く場所です。
3.15 proc
processの略です。
現在動いているプロセスや、カーネルの情報をファイルのように見せる特殊な仮想ファイルシステム3です。
代表的なものとして、以下のようなファイルがあります。
/proc/cpuinfo CPUとシステムアーキテクチャの情報
/proc/meminfo メモリの情報
/proc/version カーネルの情報
3.16 root
rootユーザーのホームディレクトリです。
3.17 run
システム起動後に作られる、一時的な実行時情報が置かれます。このディレクトリ下のファイルは、起動プロセスの開始時に消去(必要に応じて削除または切り捨て)されなければなりません。
たとえば、サービスのPIDファイル、ソケット、ロックファイルなどが置かれます。
再起動後も保存しておきたいデータを置く場所ではありません。
ちなみに、かつては/var/runディレクトリがこの役割を担っていました。しかし、以下の通り/runに統合されています。
$ ls -ld /var/run
/var/run -> /run
3.18 sbin
system binaryの略です。
システム管理用コマンドが置かれます。
私の環境だとusr mergeによって実体が/usr/sbinに統合されています。
$ ls -ld /sbin
/sbin -> usr/sbin
少し勘違いされがちなのは、/sbinにあるコマンドがシステム管理用のコマンドだからといって、一般ユーザーが実行できないわけではないということです。
例えば、/sbin/ipコマンドは、ネットワークの情報を見るだけなので実行することができます。
3.19 sbin.usr-is-merged
binと同様に、/sbinは/usr/sbinに統合されていることを示しています。
3.20 snap
Snapパッケージに関係する場所です。
SnapはCanonicalが提供しているアプリ配布形式です。
Snapでインストールされたアプリが、ここにマウントされたり配置されたりします。
3.21 srv
serviceの略です。
サーバーが提供するデータを置くための場所です。
3.22 sys
/sysはカーネルやデバイス情報を扱うための仮想ファイルシステムです。
/procと似ていますが、/sysは特にデバイス、ドライバ、カーネル内部の構造に関係します。
3.23 tmp
一時ファイルの置き場所です。
多くのシステムでは、再起動すると/tmpの中身を削除することがあります。大事なファイルは置かないようにしましょう。
3.24 usr
多くのプログラム、ライブラリ、ドキュメントなどを置きます。ここには、共有可能な読み取り専用データが入ります。
中身はこんな感じ。
$ ls /usr
bin games include lib lib64 libexec local sbin share src
これまで見てきた通り、/binや/sbin、/libが統合されています。
usrと見ると、userの略でまるでユーザディレクトリがあるように感じられます。しかし、これは間違いです。
たしかに、初期のUnix実装では/usrはユーザーのホームディレクトリが配置される場所でした。つまり、/usr/someoneは、現在/home/someoneとして知られるディレクトリでした4。しかし、現在ではそのような使い方はされていません。
/usr/local
/usr/local は、ディストリビューションのパッケージ管理とは別に、そのマシンの管理者が手動で入れたソフトウェアを置く場所として使われます。
たとえば、自分でソースコードからビルドしてインストールしたプログラムが/usr/local/bin に入ることがあります。
3.25 var
variableの略です。
変化するデータが置かれます。
代表的なものとして、以下のようなファイルがあります。
/var/log ログ
/var/cache キャッシュ
/var/lib アプリケーションの状態データ
/var/spool 印刷・メールなどの処理待ちデータ
/var/tmp 再起動後も残る可能性がある一時ファイル