Linux ファイルシステム

# はじめに

**Everything is a file**

UNIX 哲学には「すべてはファイルである」という設計思想がある。

この思想に基づいて構築された Linux では **全ての入出力（I / O）操作は「ファイル」に対して行われる**。

**ディレクトリ、デバイスファイル、パーティション、マウントポイントは全て、「ファイル」として扱われる**。

例えばパーティションに対する操作は、パーティションを表現する [デバイスファイル](#デバイスファイル) に対して行う。

ファイルシステムを理解する上で重要なポイントは以下の 5 つ。

- **物理ディスクは、複数の論理パーティションに分割できる**
- **パーティションには、対応するデバイスファイルが存在する**
- **ファイルシステムは、パーティションに対して構築される**
- **パーティションに構築されたファイルシステムは、マウントポイントでマウントすることで、操作可能になる**
- **マウントポイントは、ディレクトリである**


## ファイルの実体

Linux のファイルシステムでは、ファイルは **ファイル名**、**データ本体**、**inode** で構成される。

- ファイル名
- データ本体
  - データブロック
  - 保存対象のデータ
- inode
  - ファイルのメタデータ
  - ファイル所有者、パーミッション、更新日時など

ディレクトリは特別なファイルという扱いになっている。

## ディレクトリの実体

ディレクトリのデータ本体部分には、

- そのディレクトリに含まれるファイルのファイル名一覧
- そのディレクトリに含まれるファイルの **inode 番号** 一覧

が保存されている。

つまりディレクトリは、ディレクトリ自身が保持しているファイル名と inode 番号のマッピング情報を保持する「ファイル」と考えればよい。

わかりづらいが、ディレクトリファイル自身のメタデータは、先述のとおりディレクトリファイルの inode として保持されている。

## inode

ファイルごとに作成される、ファイルのメタデータを管理するバイナリデータ。

**inode 番号によって識別される**。

```console:ファイルの inode 番号を確認する
$ ls -i ファイル
$ stat -c %i ファイル
```

inode には、以下のような情報が含まれている。

- ファイルの属性
- ファイルの種類（通常ファイル、ディレクトリ、リンクの種類など）
- ファイルのサイズ
- 所有者（ユーザーID、グループID）
- パーミッション
- タイムスタンプ（作成時刻、最終更新時刻、最終アクセス時刻）
- リンク数（ハードリンクの数）
- データ本体への参照

また、**ファイル名と inode 番号の対応関係はディレクトリに保存される**。

:::note info
ファイル名はディレクトリが保持していて、 inode に含まれていな
:::

## SCSI
Small Computer System Interface

通信規格の一つ。

デバイスファイル `/dev/sda` や `/dev/sdb` の `sd` は **SCSI disk** の略。

ただし、現在では SATA や USB なども `/dev/sda` などの `sd` デバイスとして扱われる。

※ [SCSI](https://qiita.com/AsahinaKei/items/627f0076fecc107ac686#scsi)

## SATA
Serial Advanced Technology Attachment

通信規格の一つ。

## PCI
Peripheral Component Interconnect

拡張カードや周辺機器を接続するためのバス規格の一つ。

PCIバスに接続されたデバイスは PCI デバイス と呼ばれる。

主な PCI デバイスには以下がある。

- GPU
- 拡張カード（[NIC](https://qiita.com/AsahinaKei/items/627f0076fecc107ac686#nic)、サウンドカード、SCSI カード）

現在は PCI Express（PCIe） が主流で、従来の PCI よりも高速なデータ転送が可能。

## UUID
Universally Unique Identifier

ストレージデバイスを一意に識別するための 128 ビットの識別子。

```console:UUIDを確認する①
$ lsblk -f
```

```console:UUIDを確認する②（Block Identifier）
$ blkid
```

## ファイルシステム

ディスク上のデータをファイル単位で操作するための基本的な仕組み。

ファイルシステムの存在によって、私たちはデータを扱う際に「ディスクの〇〇バイト目 ~ ××バイト目までのデータを読み出す」などという形式ではなく、「A ディレクトリの B ファイルを読み出す」という形式でデータを扱うことができる。

ファイルシステムにhいくつかの種類がある。

| 種類 | 特徴 |
|:-|:-|
| `ext2`<br>`ext3`<br>`ext4` | Linux で最も一般的 |
| `XFS` | 高速、大容量向け（Red Hat 系） |
| `Btrfs` | スナップショット、圧縮ができる |
| `vfat` | Windows、USB で使用される |
| `exfat` | フラッシュメモリ で使用される |
| `iso9660` | CD-ROM で使用される |

Linux が起動するとき、基本的にはルートファイルシステムがすでに存在しているが、さらにルートファイルシステム配下で別のファイルシステムが構築されることがある。

[`$ mkfs`](#-mkfs) コマンドを使用することによって、パーティションに対して作成することができる。

## ルートファイルシステム

`/`（ルートディレクトリ）を起点とするファイルシステムのこと。

`ext4` や `xfs` などのファイルシステムを使用して構築されるが、 **ルートファイルシステムという種類があるわけではない**。

カーネルがブート後、最初にマウントするファイルシステムでもある。ルートファイルシステムをマウントする [パーティション](#パーティション--mbr--gpt-) を **ルートパーティション** という。

[FHS](#fhs) の表にあるような主要なディレクトリが含まれている。

## FHS

Filesystem Hierarchy Standard

Linux や Unix 系 OS のディレクトリ構造とその役割を規定した規格。

この標準規格に従うことで、異なるディストリビューション間でも共通のディレクトリ構成を持つことになるため、管理や運用がしやすくなる。

| ディレクトリ | 説明 |
|:-|:-|
| `/` | ルートディレクトリ<br>すべてのパスの起点となる |
| `/bin` | 一般ユーザでも使用可能な基本コマンドが格納されるディレクトリ<br>`$ ls`<br>`$ cp`<br>`$ mv`<br>`$ rm` |
| `/sbin` | システム管理用コマンドが格納されるディレクトリ<br>`$ fdisk`<br>`$ shutdown`<br>[`init`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#sysvinit) |
| `/lib` | [共有ライブラリ](https://qiita.com/AsahinaKei/items/5c05499c2886a0e42f1b#%E5%85%B1%E6%9C%89%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E7%BD%AE%E3%81%8D%E5%A0%B4) が格納されるディレクトリ<br>`libc.so` など |
| `/etc` | 設定ファイルが格納されるディレクトリ<br>[`/etc/passwd`](https://qiita.com/AsahinaKei/items/2fbc4e079b1c4b847240#%E5%AE%9F%E8%A1%8C%E5%8F%AF%E8%83%BD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%95%E3%82%8C%E3%82%8B%E5%A0%B4%E5%90%88)、[`/etc/fstab`](#etcfstab)、[`/etc/ld.so.conf`](https://qiita.com/AsahinaKei/items/5c05499c2886a0e42f1b#%E5%85%B1%E6%9C%89%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E7%BD%AE%E3%81%8D%E5%A0%B4) など |
| `/dev` | デバイスファイルが格納されるディレクトリ<br>`/dev/sda`<br>`/dev/null` |
| `/home` | 一般ユーザーのホームディレクトリ<br>肥大化しやすいため、[ルートパーティション](#ルートファイルシステム) と分け、**独立したパーティションとする場合が多い** |
| `/root` | `root` ユーザーのホームディレクトリ |
| `/usr` | ユーザが利用するプログラム、ライブラリ、ドキュメントが格納されるディレクトリ<br>`/usr/bin/*`<br>`/usr/sbin/*`<br>`/usr/lib/*`<br>`/usr/local/*` |	
| `/opt` | 追加でインストールしたソフトウェアが格納されるディレクトリ<br>**独立したパーティションとする場合が多い** |
| `/proc` | カーネル情報にアクセスするための **仮想ファイル**（実際のディスク上には存在しない）が格納されるディレクトリ<br>`proc/プロセスID/fd/`：[ファイルディスクリプタ](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF) 情報<br>`/proc/cpuinfo`：CPU 情報<br>`/proc/meminfo`：メモリ情報<br>`/proc/bus/usb/*`：USB デバイス情報 など |
| `/sys` | デバイスやドライバの情報（[udev](#udev)）が格納されるディレクトリ |
| `/media` | USB メモリや CD-ROM などの自動マウントに使われる |
| `/mnt` | 外部ストレージやネットワークドライブを手動で一時的にマウントするためのマウントポイントとなるディレクトリ |
| `/boot` | システムの起動（ブート）に関わるファイルが格納されるディレクトリ<br>カーネル本体（vmlinuz）もここにある |
| `/var` | ログや頻繁に更新されるデータが格納されるディレクトリ<br>**独立したパーティションとする場合が多い**<br>`var/cache`：一時的なキャッシュファイル<br>`/var/log`：ログファイル<br>`/var/lock`：[排他制御](https://qiita.com/AsahinaKei/items/b05b5b59e94840cbbaa1#%E3%83%9F%E3%83%A5%E3%83%BC%E3%83%86%E3%83%83%E3%82%AF%E3%82%B9%E6%8E%92%E4%BB%96%E5%88%B6%E5%BE%A1) に使用するためのロックファイルが格納されるディレクトリ<br>`/var/run`：システムの状態を示すファイル |
| `/tmp` | 一時ファイル<br>[スティッキービット](https://qiita.com/AsahinaKei/items/2fbc4e079b1c4b847240#%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AD%E3%83%BC%E3%83%93%E3%83%83%E3%83%88) が設定されることが多い<br>**独立したパーティションとする場合が多い** |

## 仮想ファイルシステム
Vertual File System, VFS

実際の物理的なストレージやディスク上（HDD や SSD など）に存在しないファイルを、ファイルシステムの中で仮想的なファイルやディレクトリとして提供する仕組み。

[前述](#はじめに) の通り、UNIX 哲学には「Everything is a file」という哲学があるため、カーネルや OS が内部的に必要とする情報も、「ファイル」として扱われる。

【代表的な仮想ファイルシステム】

- `/proc/`
    - カーネル、プロセス、ハードウェアの状態
    - `/proc/cpuinfo`：CPU 情報
    - `/proc/プロセスID/fd/`：[ファイルディスクリプタ](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF) 情報
- `/sys/`
    - システムの設定やデバイス情報
- `/dev/`
    - デバイスファイル
    - [`/dev/null`](#特別な意味を持つデバイスファイル)：データ破棄用
    - [`/dev/zero`](#特別な意味を持つデバイスファイル)：`0`埋め用

## デバイスファイル

カーネルが周辺機器、デバイス、システム内のリソースにアクセスするための **インターフェースとして機能する** 特別なファイル。

物理デバイスに対応するデバイスファイルは、通常 `/dev/` 配下に作成されるが、パーティションのように、動的に生成されたり削除されるファイルもある。

デバイスファイルが「通常のファイル」と同様のインターフェースを提供することにより、

- `open`
- `read`
- `write`
- `close` 

などの、通常はファイルに対して行う操作（[システムコール](https://qiita.com/AsahinaKei/items/22d9fae93cabfbf137ee#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B3%E3%83%BC%E3%83%AB)）を、デバイスに対しても同様に行うことが可能となる。

つまり **デバイスをファイルのように扱う** ことが可能になる。

デバイスファイルはファイルシステムに組み込まれているが、カーネルが管理するインターフェースであり、実際のストレージ上には「通常のファイル」が持つような [データ本体](#はじめに) が存在するわけではない。

:::note info
デバイスファイルの実体はストレージ上には存在しない
:::

**デバイスファイルにアクセスを行うのはカーネル（のデバイスドライバ）であり、操作できるユーザは `root` のみ**。

種類として キャラクタデバイス と ブロックデバイス がある。


## キャラクタデバイス
Character Device

**1 byte 単位（文字単位）** でデータをやり取りするデバイスファイル。

- [端末](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#-tty)（`/dev/tty1`、`/dev/pts/0`）
- キーボード（`/dev/input/event0`、`/dev/input/mouse0`）
- マウス（`/dev/input/event0`、`/dev/input/mouse0`）
- シリアルポート（`/dev/ttyS0`、 `/dev/ttyUSB0`）

[ファイル種別](https://qiita.com/AsahinaKei/items/2fbc4e079b1c4b847240#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%A8%AE%E9%A1%9E) は `c` で表示される。

```console:キャラクタデバイス
$ ls -l /dev/ttys1
crw--w----  1 root  tty  0x10000000 Nov  1 05:34 /dev/ttys1
```

**文字単位でストリーム的にデータの入出力を行うため、バッファなどを使用しない即時性が求められるキーボード、マウスなどの入出力に適している**。

キャラクタデバイスに対して読み書きは行えるが、シーク操作は行うことができない。シーク操作とは、デバイス内でアクセスする場所を変更する操作を指す。

## ブロックデバイス

**ブロック単位（一定サイズ）** でデータをやりとりするデバイスファイル。

- ハードディスク（`/dev/sda`、`/dev/sdb`、`/dev/sdc`）
- USBストレージ（`/dev/sda`、`/dev/sdb`、`/dev/sdc`）
- CD / DVD ドライブ（`/dev/sr0`、`/dev/sr1`、`/dev/sr2`）

ファイル種別は `b` で表示される。

```console:ブロックデバイス
$ ls -l /dev/disk0
brw-r-----  1 root  operator  0x1000000 Oct 26 21:18 /dev/disk0
```

## パーティション ( MBR / GPT )

物理ストレージ（HDD や SSD）を複数の論理的な領域に区切る仕組み。

それぞれのパーティションは OS からは独立したストレージ領域として認識される。

![LPIC (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/36bfaa4b-ce0b-4b1c-b5c3-f173aa212ac6.png)

例えばデバイス `/dev/sdb` をファイルシステムとして利用するには以下の操作が必要になる。

1. パーティション（`/dev/sdb1`）の作成
    a. [`$ fdisk`](#-fdisk---gdisk)
2. 作成したパーティションに対するフォーマット（[ファイルシステム](#ファイルシステム)）
    a. [`$ mkfs`](#-mkfs)
3. パーティション（`/dev/sdb1`）のマウント
    a. [`$ mount`](#-mount)

[ルートファイルシステム](#ルートファイルシステム) をマウントするパーティションは **ルートパーティション** と呼ばれる。

![LPIC (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/838b2a6d-7b2a-4d39-a5c8-7aee2134d3db.png)


ファイルシステムにはいくつかの種類（`ext4`、`ntfs`、`fat32`）があり、それぞれのパーティションには異なるファイルシステムを作成することも可能。

パーティションの方式には **MBR**（Master Boot Record） と  **GPT**（GUID Partition Table） がある。

GPT は MBR の後継版であり、作成できるパーティションの数が異なる。

- MBR → 4 個 
- GPT → 128 個

MBR では作成できるパーティションは最大 4 つであるため、それ以上のパーティションが必要となった場合に、以下のような仮想的にパーティションを増やす仕組みがある。

- **基本パーティション**
    - 最大 4 つ作成可能
    - ファイルシステムを設定する
    - `/dev/sda1`、`/dev/sda2`、`/dev/sda3`、`/dev/sda4`
- **拡張パーティション**
    - 論理パーティションを作成するための領域
    - 基本パーティションの内の 1 つを拡張パーティションとすることができる
    - 通常、`/dev/sda4` が選択される
- **論理パーティション**
    - 拡張パーティション内に作成される仮想パーティション
    - `/dev/sda5`、`/dev/sda6`、...


## マウント

HDD、SSD、USB などの外部のストレージを OS に認識させ、自身のディレクトリツリーに組み込むことで、そのストレージのファイルシステムにアクセスできるようすること。

Windows では独立したドライブレター（`C:` や `D:`）でストレージを識別するが、Linux ではルートディレクトリ（`/`） を起点とするディレクトリ構造の一部として接続する。

![LPIC (19).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/fbb65165-57b0-4658-8b69-9fcefce7a8ae.png)

マウントは、特定のパーティションに対して行われ、ファイルシステムとの起点、接続点となる。

![LPIC (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/b2098137-156d-4dfb-ac85-030c6a3250e9.png)

マウントするディレクトリは、」中身が空でなければならない（[空にしないとどうなるか](#マウントを理解する)）。

マウントするディレクトリを **マウントポイント** と呼び、デバイス上のファイルシステムのルートディレクトリは、このマウントポイントに統合される。

**通常は `/dev/sdb` などのディスク全体ではなく、その中の `/dev/sdb1` などの [パーティション](#パーティション--mbr--gpt-) をマウントする**。

```console:USBドライブ（/dev/sdb1）を /mnt/usb でマウントする
$ mount /dev/sdb1 /mnt/usb
```

![LPIC (22).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/f519f9c3-9d28-461c-b87d-7dd4530fe7b6.png)


:::note info
**パーティションとして作成された「デバイスファイル」に対して、「ディレクトリ」をマウントする**
:::

:::note info
**マウントポイントにする予定のディレクトリは空である必要がある**
:::


## デバイスドライバ

カーネルがハードウェアを制御するためのインターフェースとして機能するソフトウェア。

Linux では **カーネルモジュール** として実装されることが多い。

カーネルモジュールはカーネルの一部として機能し、カーネルを再起動することなく追加、削除することができる。また、デバイスドライバをカーネルモジュールとしてカーネルに取り込むことは **ロードする** と表現される。


## udev
Universal Device Management

カーネルが検出したデバイスに対して、適切なデバイスノード（`/dev`）を動的に作成、管理するシステムまたは仕組み。

主要なLinuxディストリビューションに標準搭載されている。

USBなどのデバイスが接続された際に、カーネルは sysfs（`/sys/`）と呼ばれる仮想ファイルシステムにデバイス情報（`/sys/bus/usb/devices/1-1/` など）を作成する。

sysfs は仮想的に作成されるファイルで、ディスク上ではなくメモリ上に存在し、ベンダーID（idVendor）、製品ID（idProduct）、デバイス名（product） などの情報が格納されている。

udev は `/sys` ディレクトリを監視し、新しいデバイスが追加されると自動的に `/dev/` にデバイスファイルを作成する。

このときの動作を `/etc/udev/rules.d` ディレクトリの設定ファイルを編集することによって制御することができる。つまり、特定のデバイスに対する自動処理に独自のルールを作成することができる。

## スワップ

物理メモリ（[RAM](https://qiita.com/AsahinaKei/items/8fede81f102f848cb6ba#ram)）の容量が不足した際に、[ストレージ](https://qiita.com/AsahinaKei/items/8fede81f102f848cb6ba#%E8%A3%9C%E5%8A%A9%E8%A8%98%E6%86%B6%E8%A3%85%E7%BD%AE) 上で確保される一時的なメモリ領域。

- パーティションをスワップとして利用する方法
- ファイルをスワップとして利用する方法

がある。

## デバイスファイル名のアルファベット

デバイスファイル `/dev/sdX` の `X` の位置にあるアルファベット部分 （`a`、`b`、`c`、…） は、物理ディスクごとに付与された識別子を表す。

起動順や接続順、OSがデバイスを認識した順番で `sda`、`sdb`、`sdc` という様に名前が付与される。

## デバイスファイル名の数字

デバイスファイル `/dev/sdaY` や `/dev/sdbY`  の `Y` の位置にある数字（`1`、`2`、`3`、 …） は、ディスク内のパーティション番号を表す。

`/dev/sda` にパーティションを作成した場合、`/dev/sda1`、`/dev/sda2` のように番号が続く。

## 特殊な意味を持つデバイスファイル

| デバイスファイル | 意味 |
|:-|:-|
| [`/dev/null`](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#devnull) | 書き込んだデータをすべて破棄する<br>コマンド出力を破棄する際に使用される |
| ` /dev/full` | 常に「ディスクいっぱい」のエラーを返す<br>ディスクがいっぱいの状態が必要なテストなどで利用される |
| `/dev/zero` | 無限にゼロ (`\0`) を返す<br>ファイルの初期化、メモリのクリアに利用される |
| `/dev/random` | 真の乱数を生成する（低速）<br>高い安全性が求められる暗号鍵の生成で利用される |
| `/dev/urandom` | 擬似的な乱数を生成する（高速）<br>APIキー、セッションID、一時パスワードの生成など、暗号的に安全だが高速な乱数が求められる場面で利用される |
| ` /dev/tty` | 現在の [制御端末](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#-tty) を返す |
| `/dev/console` | 主に [`init システム`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#sysvinit) やカーネル側が入出力用に使用する<br>ログメッセージの出力先として利用される | 

## `Read-only file system` と出力されたら...

`/` や `/etc` がシステム起動時に読み取り専用モード（`ro`：read only）でマウントされている場合、配下のファイルを編集しようとすると 

```
Read-only file system
```

と出力されることがある。

`$ mount` コマンドで一覧表示することで `ro` かどうかが確認できる。

```console:ro モードであることを確認する
$ mount
/dev/sda1 on / type ext4 (ro)
```

このような場合に、マウントし直すことで書き込み可能にすることができる。マウント済みのデバイスファイルは、再マウント時に指定する必要がない。

```console:/ （ルートディレクトリ）を読み書きモード（rw：read write）でマウントし直す
$ sudo mount -o remount,rw /
```

ただし、この変更は再起動すると元（`ro`）に戻る可能性がある。

## デバイスファイルとマウントポイントの違い

どちらもデータを処理するためのインターフェースとして機能するが、利用する主体が異なる。

**デバイスファイルは**、

カーネルによって低レベルなデータ処理を行うためのインターフェースとして機能する。実際には `read()` や `write()` などの [システムコール](https://qiita.com/AsahinaKei/items/22d9fae93cabfbf137ee#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B3%E3%83%BC%E3%83%AB) を通じて、カーネルがデバイスとやり取りしている。

例えば、以下のような [`$ dd`](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#-dd) を用いた操作ではマウントポイントは意識されない。

```console:デバイスを丸ごとバックアップする
$ dd if=/dev/sdb1 of=backup.img
```

一方 **マウントポイントは**、

ユーザによって直感的な（高レベル）ファイルシステム操作を行うためのインターフェースとして機能する。

`/mnt/usb/` のようなマウントポイントは、ユーザがデバイス内のファイルにアクセスするためのディレクトリパスであり、`/mnt/usb/sample.txt` のように通常のファイルとして操作できる。

```console:USBのファイルをローカル環境にコピーする
$ cp /mnt/usb/sample.txt /home/user1/Documents/
```    

ただし、マウント前の `/mnt/usb` ディレクトリは単なる空のディレクトリであり、マウント後にデバイス内のファイルシステムと接続される。

デバイスファイル (`/dev/sdb1` など) はマウントしなくても `$ dd` などで直接操作できるが、ファイル単位のアクセスはできない。ファイル単位の読み書きはマウントポイントを経由する必要がある。

## マウントを理解する

マウントはパーティションとして作成されたデバイスファイルに対して「ディレクトリ」を指定して行われる。

![file_system (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/95036c42-a57a-4bea-8080-24fef079530d.png)


サーバを構築する際、 [FHS](#fhs) にあるディレクトリのうち、下記のディレクトリはルートパーティションとは独立したパーティションとして設計されることが多い。

|ディレクトリ| パーティションを分ける利点 |
|:-|:-|
| `/ (ルート)` | ルートファイルシステムの起点 |
| `/home` | ユーザデータをユーザごとに管理しやすくなる |
| `/var` | ログや頻繁に変更されるデータを独立させ、ルートの容量圧迫を防ぐことができる |
| `/boot` | ブートローダ関連のファイルを独立させることで、システムの互換性や安定性を高めることができる |
| `/tmp` | 一時ファイルの保存領域を分け、不要なデータで `/` を圧迫しないようにすることができる |
| `/usr` | ソフトウェアやライブラリの保存領域を分け、管理しやすくなる |
| `/opt` | 追加インストールしたソフトウェアを分けて管理することができ |

実際には以下のような対応で設定されることが多い。

| パーティション | マウントポイント | 用途 |
|:-|:-|:-|
| `/dev/sda1` | `/boot/` | OSのカーネルやGRUBの設定を格納 |
| `/dev/sda2` | `/` | ルートファイルシステム |
| `/dev/sda3` | `/home/` | 各ユーザのデータ |
| `/dev/sda4` | `/var/` | ログ、データベース、メールなど |

また下記のディレクトリについては、独立したパーティションとして分けることはあまりない。

| ディレクトリ | パーティションを分けない理由 |
|:-|:-|
| `/bin/` | 基本コマンドが含まれており、システム起動に必要なため |
| `/sbin/` | `/bin` と同様、システム管理コマンドがあるため |
| `/lib/` | `/bin` や `/sbin` のコマンドが必要とするライブラリのため |
| `/etc/` | 設定ファイルが格納されており、システムの一貫性を保つため |
| `/dev/` | [仮想ファイル](#仮想ファイルシステム) を含むディレクトリのため |
| `/proc/` | 仮想ファイルが格納されるディレクトリのため |
| `/sys/` | 仮想ファイルが格納されるディレクトリのため |


ルートディレクトリをマウントするパーティションと、ルートディレクトリ内の特定のディレクトリをマウントする様子を図にしてみた。

![LPIC (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/8d9a685f-0ad3-4762-bc26-db36cb708272.png)

ここで、もしマウントする前に `/home/` 配下に何らかのファイルが存在していたら、どうなるのかが気になった。

調べてみると、あるディレクトリに別のファイルシステムをマウントすると、そのディレクトリのもともとの内容は **見えなくなる**ということだった。

`/home/file1` というファイルが既に存在している状態で `home/` ディレクトリをマウントに利用すると、マウント先のデバイスのファイルシステムが表面化し、`/home/file1` は見えなくなる。マウントを解除すると、再び `/home/file1` が見えるようになる。

つまり、マウントポイントにする予定のディレクトリは空である必要がある。

[Mac に Ubuntu をインストール](https://qiita.com/AsahinaKei/items/63085a778cbdd29dad4a) した際は、こんな設定画面が出ていた。

![Screenshot 2025-02-16 at 16.50.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/6841c87f-01f9-4143-893a-a1d4ba3b0f36.png)

## スワップファイルを作成する

[`$ fallocate`](#fallocate) を使用する方法。

```console:1Gのスワップ用ファイル swapfile を作成する
$ sudo fallocate -l 1G ./swapfile
```

スワップファイル作成後は [`$ chmod`](https://qiita.com/AsahinaKei/items/2fbc4e079b1c4b847240#-chmod) でパーミッションを変更し、ファイル所有者以外がアクセスできないようにするのが一般的。

```console:権限を変更
$ sudo chmod 600 ./swapfile
```

また `$ fallocate` でなく、[`$ dd`](https://qiita.com/AsahinaKei/items/301b88e464c23aba231e#-dd) を使用する方法もある。

`$ dd` の場合、実際にデータを `0` 埋めによって書き込むため処理が低速だが、一部のファイルシステム（XFS）では `$ fallocate` で作成したファイルをスワップにできない場合がある。

```console:$ dd を使ってスワップファイルを作成する
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
```

※ [`/dev/zero`](#特殊な意味を持つデバイスファイル)

## `$ df` と `$ du` の違い

`$ df`
ファイルシステム（[パーティション](#パーティション--mbr--gpt-)）ごとの使用状況を表示する。ファイルごとの使用量はわからない。

`$ du`
ディレクトリやファイル単位の使用量を表示する。また使用量を表示するため、空き容量はわからない。

## `$ fdisk` / `$ gdisk` / `parted` の違い

| 機能 | `$ fdisk` | `$ gdisk` | `$ parted` |
|:-:|:-:|:-:|:-:|
| MBR | ◯ | × | ◯ |
| GPT | × | ◯ | ◯ |
| 2TB 以上対応 | × | ◯ | ◯ |
| 対話モード | ◯ | ◯ | ◯ |
| スクリプト実行 | × | × | ◯ |
| パーティションサイズ変更 | × | × | ◯ |


#  `/etc/fstab`

`/etc/fstab` ファイル（File System Table）に設定されたストレージは起動時に `systemd` によって自動的にマウントされる。

日常的に使用するストレージにはこの設定をしていることが多い。

以下の様な形式で設定を記述する。

```:/etc/fstab
デバイスファイル マウントポイント ファイルシステム オプション dump fsck
UUID=デバイスのUUID マウントポイント ファイルシステム オプション dump fsck
```

```:例
/dev/sda1    /boot    ext3    defaults    1    1
UUID=12345678-90ab-cdef-1234-567890abcdef    /        ext4    defaults    0    1
UUID=abcdef12-3456-7890-abcd-ef1234567890    /home    ext4    defaults    0    2
```

| 設定項目 | 説明 |
|:-|:-|
| デバイスの UUID<br>デバイスファイル名 | デバイスファイル名でも良いが、[UUID](#uuid) を使うとデバイス名の変更に影響されない。<br>UUID は `$ lsblk -f` で確認できる。 |
| マウントポイント | [マウントポイント](#マウント) となるディレクトリ<br>[スワップ](#-mkswap---swapon) 有効化の際は `none` |
| ファイルシステム | [ファイルシステム](#ファイルシステム)<br>`ext4`、`xfs`、`ntfs` など |
| オプション |  パフォーマンス、セキュリティ、利便性に関わるオプション（複数指定可）<br>`defaults`：デフォルトのオプションセット（通常）<br>`sw`：スワップ領域としての標準オプションセット<br>`user`：一般ユーザもマウントできる（アンマウントはマウント実行ユーザのみ）<br>`users`：一般ユーザもマウントできる（全てのユーザがアンマウント可能）<br>`nouser`：一般ユーザのマウント禁止<br>`auto`：`$ mount -a` 実行時にマウントされる<br>`noauto`：`$ mount -a` 実行時にマウントされない<br>`ro`：読み取り専用（read only）<br>`rw`：読み書き可能（read write） |
| dump フラグ | `$ dump` コマンドを実行した時にバックアップ対象とするかしないか有無。実際の運用ではほとんどのシステムで `$ dump` コマンドは使われないため `0` が一般的。<br>`0`：バックアップ対象としない<br>`1`：バックアップ対象とする |
| fsck | 起動時にファイルシステムの整合性を [`$ fsck`](#fsck) でチェックするかどうか（file system check）、またチェックする場合の優先順位（ファイルシステムの破損を防ぐために使用される）<br>`0`：チェックしない<br>`1`：最優先でチェックされる。ルートファイルシステム（`/`）専用。<br>`2`：ルート以外のパーティションでチェックを行う場合は `2` を使用する |

例えば、Ubuntu のルートファイルシステム `/` や `/home`、`/boot` などは、`/etc/fstab` に記載されているため、起動時に自動でマウントされる。

[デスクトップ環境](https://qiita.com/AsahinaKei/items/63085a778cbdd29dad4a#%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E7%92%B0%E5%A2%83)（GNOME、KDE など）では、`udisks2` や `gvfs` などのデーモンを利用して自動マウントされることもある。

# `$ file`

```console:ファイルの種類を調べる
$ file ファイル
```

# `$ touch`

```console:新規ファイルを作成する
$ touch ファイル名
```

# `$ mkdir`
Make Directory

```console:ディレクトリを作成する
$ mkdir ディレクトリ名
```

```console:指定したディレクトリの親ディレクトリも自動作成する（parents）
$ mkdir -p ディレクトリパス
```

```console:パーミッションを指定してディレクトリを作成する（mode）
$ mkdir -m パーミッション ディレクトリ名
```

`$ mkdir -m` で指定できる [パーミッション](https://qiita.com/AsahinaKei/items/2fbc4e079b1c4b847240#%E6%95%B0%E5%80%A4%E5%BD%A2%E5%BC%8F) は数値形式のみ。

# `$ rmdir`

ディレクトリを削除する。ただし、**ディレクトリ内が空の場合に限る**。

```console:ディレクトリを削除する
$ rmdir ディレクトリ名
```

# `$ pwd`
Print Working Directory

```console:カレントディレクトリを表示する
$ pwd
```

# `$ cd`
Change Direcotry

```console:カレントディレクトリを移動する
$ cd パス # 相対パスもしくは絶対パスを指定できる
```

`-` を指定すると一つ前の作業ディレクトリに戻ることができる。

```console:一つ前の作業ディレクトリに戻る
$ cd -
```

# ` $ mv`
Move

ファイル、ディレクトリを移動する。もしくはファイル名、ディレクトリ名を変更する。複数のファイルを同時に操作することはできない。

```console:ファイルを移動する
$ mv 旧パス 新パス
```

移動先の指定はディレクトリ（末尾に `/`）でも良い。

```console:ファイルを指定したディレクトリ配下へ移動する
$ mv ファイル ディレクトリ/
```

```console:ディレクトリを移動する
$ mv 旧ディレクトリ/ 新ディレクトリ/
```

```console:ファイル名を変更する
$ mv 旧ファイル名 新ファイル名
```

```console:ディレクトリ名を変更する
$ mv 旧ディレクトリ名/ 新ディレクトリ名/
```

# `$ cp`

```console:ファイルやディレクトリをコピーする
$ cp コピー元 コピー先
```

```console:複数ファイルをまとめてコピーする
$ cp コピー元1 コピー元2 ディレクトリ/
```

```console:ディレクトリごとコピーする（recursive）
$ cp -r コピー元ディレクトリ　コピー先ディレクトリ
```

`-p` オプションで、ファイルの所有者、パーミッション、最終更新時刻などのタイムスタンプを維持したままコピーが行えr

```console:属性情報を保持したままコピーする（preserve）
$ cp -p コピー元ディレクトリ　コピー先ディレクトリ
```

# `$ rm`
Remove

```console:ファイルを削除する
$ rm ファイル
```

```console:複数のファイルをまとめて削除する
$ rm ファイル1 ファイル2 ファイル3 
```

```console:カレントディレクトリ内のすべてのファイルを削除する
$ rm *
```

```console:ファイルの存在有無を問わない（fource）
$ rm -f ファイル
```

```console:削除前の確認あり（interactive）
$ rm -f ファイル
```

```console:ディレクトリを含むファイルを再帰的に削除する（recursive）
$ rm -r ディレクトリ
```

# `$ dirname`
Directory Name

```console:ファイルパスのディレクトリ部分を抽出する
$ dirname ファイルパス
```

```console:親ディレクトリを表示する
$ dirname ディレクトリパス/
```

# `$ lsblk`

```console:ブロックデバイスを一覧表示する
$ lsblk
```

※ [ブロックデバイス](#ブロックデバイス)

# `$ lspci`

```console:システムに接続されているPCIデバイスを一覧表示する（-v : 詳細表示）
$ lspci -v
```

[PCI](#pci) デバイス：NIC、Bluetooth アダプタ、[SCSI](#scsi) コントローラ など

# `$ lsusb`

```console:システムに接続されているUSBデバイスを一覧表示する（-v : 詳細表示）
$ lsusb -v
```

# `$ lsscsi`

```console:SCSI デバイスの情報を一覧表示する（-v：詳細表示）
$ lsscsi -v
```

SCSI デバイス：HDD、SSD、CD / DVD ドライブなど

# `$ lshw`
ls hardware

```console:システム全体のハードウェア（CPU、メモリ、マザーボード、ネットワークアダプタ、ストレージデバイス）情報を詳細に表示する
$ sudo lshw
```

# `$ lscpu`

```console:CPU に関する情報を表示する
$ lscpu
```

[`/proc/cpuinfo`](#仮想ファイルシステム) の情報が表示される。

# `$ lsof`
List Open Files

システム内で開かれているファイルやソケットを一覧表示する。

```console:システム上のすべての開いているファイルを一覧表示する
$ lsof
```

```console:特定のプロセスが開いているファイルを調べる
$ lsof -p PID
```

```console:特定のユーザが開いているファイルを調べる
$ lsof -u ユーザ名
```

```console:特定のファイルを開いているプロセスを調べる
$ lsof ファイル名
```

```console:特定のポートを使用しているプロセスを調べる
$ lsof -i:ポート番号
```

# `$ lsmod`

`/proc/modules` の情報が表示される。

```console:現在カーネルにロードされているカーネルモジュール（デバイスドライバ）を一覧表示する
$ lsmod
```

# `$ fdisk` / `$ gdisk`

パーティションを作成するためのコマンド。

:::note alert
ストレージ内のデータを破壊できるコマンドのため、使用には十分注意する
:::

fixed disk　：　MS-DOS 時代から使われている [MBR](#パーティション--mbr--gpt-) 形式のパーティション管理ツール
GPT fdisk　：　[GPT](#パーティション--mbr--gpt-) 形式のディスクを管理するための `$ fdisk` に相当するツール

```console:パーティション情報を表示する
$ sudo fdisk -l パーティション
$ sudo gdisk -l パーティション
```

`-l` をつけない場合、対話モードに切り替わる。

```console:パーティションを作成する
$ sudo fdisk デバイス
$ sudo gdisk デバイス
```

対話モードに切り替わったら **サブコマンド** によって操作を行う。

| サブコマンド | 説明 |
|:-:|:-|
| `m` | ヘルプを表示（menu） |
| `p` | 現在のパーティション情報を表示（print） |
| `n` | 新しいパーティションを作成（new） |
| `d` | 既存のパーティションを削除（delete） |
| `t` | パーティションのタイプを変更（type） |
| `w` | **変更を保存して終了**（write） |
| `q` | 変更せずに終了（quit） |

# `$ parted`
Partition Editor

パーティションを作成するためのコマンド。

:::note alert
ストレージ内のデータを破壊できるコマンドのため、使用には十分注意する。
`$ fdisk` や `$ gdisk` では、変更を `w` で書き込むまで確定しないが、`$ parted` は即時適用される。
:::

[MBR](#パーティション--mbr--gpt-) と [GPT](#パーティション--mbr--gpt-) の両方をサポートする高機能なパーティション管理ツール。

対話モードを使用せずにスクリプトによって一括処理することもできる。

```console:基本構文
$ parted デバイス
```

`$ parted` を実行すると、対話モードに切り替わる。

対話モードを使用しない場合、`-s` オプションを利用する。

```console:基本構文（対話モードを使わない）
$ parted デバイス -s サブコマンド
```

| サブコマンド | 説明 |
|:-|:-|
| `check 番号` | ファイルシステムの簡単なチェックを行う |
| `mklabel` | 新しいパーティションテーブルを作成する（make label） |
| `mkpart 種類 開始 終了` | 指定した種類のパーティションを作成する（make partition） |
| `rm 番号` | 指定したパーティションを削除する |
| `p` / `print` | パーティションテーブルを表示する |
| `q` / `quit` | 終了する |


# `$ mkfs`
make filesystem

[パーティション](#パーティション--mbr--gpt-) 上にファイルシステムを作成する。

`-t` オプションで種類を指定することができる。もしくはそれぞれのファイルシステムごとのコマンドも用意されている。

```console:ファイルシステムを作成する
$ mkfs -t ファイルシステム デバイス # デバイス = パーティション
$ mkfs.ファイルシステム デバイス
```

```console:例
$ mkfs -t ext4 /dev/sdb1
$ mkfs.ext4 /dev/sdb1
```

# `$ fsck`
File System Check

ファイルシステムの整合性をチェックし、必要に応じて修復する。

クラッシュ、強制終了、電源断などのディスクの異常発生時に、ファイルシステムの破損を検出・修復するために使用される。
 
:::note alert
チェックするファイルシステムをアンマウントした状態で実行する必要がある！
:::

```console:ファイルシステムの整合性をチェック、必要に応じて修復する
$ fsck デバイス
```

[ファイルシステム](#ファイルシステム) ごとに `$ fsck` を使い分ける必要はなく、内部的に、現在使用中のファイルシステムに応じたプログラムが呼び分けられる仕組みになっている。

```console:実際には実行しないが、実行した場合の処理を表示する
$ fsck -N デバイス
```

```console:/etc/fstab の全パーティションをチェックする
$ fsck -A
```

※ [`/etc/fstab`](#etcfstab)

# `$ tune2fs`
Tune ext2 File System

`ext2`、`ext3`、`ext4` ファイルシステムのパラメータを変更、調整（tune）する。

```console:基本構文
$ sudo tune2fs デバイス
```

```console:現在の設定を表示する
$ sudo tune2fs -l デバイス
```

# `$ debugfs`

`ext2`、`ext3`、`ext4` ファイルシステムのデバッグ用ツール。

対話形式でデバイスをオープンして、内部のファイルシステムを解析する。

```console:読み取り専用モードでオープン、解析する
$ debugfs デバイス
```

対話モードに遷移したら、`$ quit` で終了できる。

```console:読み書きが可能なモードでオープン、解析する
$ debugfs -w デバイス
```

:::note alert
読み書きモードで実行した場合、ファイルシステムが破損することがある！
:::


# `$ mount`

```console:デバイスを特定のディレクトリにマウントする
$ mount デバイス マウントポイント  # デバイス = パーティション、マウントポイント = ディレクトリ
```

```console:ファイルシステムを指定してマウントする
$ mount -t ファイルシステム デバイス マウントポイント
```

```console:/etc/fstab に記載されたエントリのオプションに auto が設定された全てのファイルシステムをマウントする
$ mount -a
```

引数無しで実行すると、マウント済みのデバイス一覧を表示することができる。

```console:マウント済みのデバイス一覧を表示する
$ mount
```

`-o` オプションは複数のオプション引数を `,` で受け取ることができる。

```console:-o（option）
$ mount -o オプション引数1,オプション引数2,オプション引数3 デバイス マウントポイント  
```

| オプション引数 | 説明 |
|:-|:-|
| `remount` | マウント済みのファイルシステムのオプションを変更する |
| `ro` | 読み取り専用にする |
| `rw` | 読み書き可能にする |
| `noexec` | 実行可能ファイルを実行不可にする |
| `nosuid` | [SUID / SGID](https://qiita.com/AsahinaKei/items/2fbc4e079b1c4b847240#suid--sgid) を無効化する |
| `nodev` | デバイスファイルを無効化する |
| `async` | 非同期書き込みを有効化する |
| `sync` | 同期書き込み（書き込みが即時反映される）を有効化する |

`--bind` オプションを使用すると、マウント済みのパーティション内の特定のサブディレクトリを、別のディレクトリにバインドマウントすることができる。

```console:マウント済みのディレクトリ配下のディレクトリを再マウントする
$ mount --bind ディレクトリ マウントポイント
```

# `$ umount`

デバイスのマウントを解除（アンマウント、取り外し）する。

アンマウントすることで、デバイスを安全に取り外すことができる。

```console:デバイスをアンマウントする
$ umount マウントポイント
$ umount デバイス
```


# `$ mkswap`
make swap

パーティション上にスワップ領域を作成する。

```console:スワップ領域を作成する
$ sudo mkswap デバイス # デバイス = パーティション
```

作成したスワップ領域は `$ swapon` で有効化される。

# `$ swapon`
swap on

```console:スワップを有効化する
$ swapon デバイス # デバイス = パーティション
```

`$ swapon` は、ログイン中のシェルセッション環境下でのみスワップを有効化する。そのため、特定のパーティションのスワップの有効化を行っても、再起動によってスワップが無効になるため、再度 `$ swapon` を実行する必要がある。

もし、スワップ有効化を永続化したい場合、[`/etc/fstab`](#etcfstab) に以下の設定を追加する必要がある。

```console:スワップの有効化を起動時に行うよう設定する
$ /dev/sdb1 none swap sw 0 0
```

:::note info
`$ mkswap` で作成したスワップ領域は `$ swapon` で有効化する必要がある。
永続化する場合、`/etc/fstb` への設定追加が必要。
:::

# `$ df`
Disk Free

```console:ディスクの空き容量や使用状況を確認する
$ df 
```

```console:見やすい形式（KB、MB、GB）で表示する（human-readable）
$ df -h
```

```console:特定のディレクトリやデバイスを対象とする
$ df -f ディレクトリ
$ df -f デバイス
```

`-i` オプションで [inode](#inode) の数を表示することもできる。Linux におけるファイルは、それぞれに対応する inode を必ず一つ持つため、inode の数はファイルの数を表す。

```console:inode の数（ファイル数）を確認する
$ df -i
```

それぞれのファイルシステムには、作成可能な inode の個数が決まっており、ディスクに空き容量があったとしても inode に空きがない限り、ファイルを作成することができない。

# `$ du`
Disk Usage

```console:特定のファイル、ディレクトリの使用量を確認する
$ du ファイル
$ du ディレクトリ
```

引数を指定しない場合、ディレクトリ単位で使用容量が表示される。

```console:カレントディレクトリの使用状況を表示する
$ du
```

```console:見やすい形式（KB、MB、GB）で表示する（human-readable）
$ du -h
```

# `$ modprobe`
probe=探査する、調査する

モジュールが必要とする別のモジュールなど、依存関係も自動で探査（probe）し、ロードすることができる。

```console:カーネルモジュールをロードする
$ sudo modprobe モジュール名
```

```console:カーネルモジュールをアンロードする
$ sudo modprobe -r モジュール名
```

# `$ fallocate`
File Allocate

ファイルシステム上に指定サイズのファイル領域を **事前に** 確保する。

物理ディスクに対してファイルとして利用する領域を事前に割り当てることにより、ディスクのフラグメンテーション（断片化）を防ぎ、書き込み時のパフォーマンスを向上させることができる。

サイズを指定するための`-l` オプションが必須。

```console:ファイル領域を確保する
$ fallocate -l サイズ ファイル名
```

```console:例
$ fallocate -l 100M ./sample  # 100MB
$ fallocate -l 1G ./sample    #   1GB
```

# `$ find`

特定のディレクトリツリー配下から、条件に一致するファイルを再帰的に検索する。

```console:条件に一致するファイルを検索開始ディレクトリ配下で探す
$ find 検索開始ディレクトリ 検索式
```

検索開始ディレクトリを省略すると、カレントディレクトリ配下が検索対象になる。

```console:カレントディレクトリ配下を検索する
$ find 検索式
```

```console:カレントディレクトリ以下のすべてのファイルとディレクトリを表示
$ find .
```

## 特殊文字の扱い

ファイル名にスペース「` `」や、コーテーション「`'`」などの特殊文字が含まれている場合のTips。

ファイル名が`hello world.txt`のようにスペースを含む場合。 

**`""` で囲う**

```console:""で囲う
$ find . "hello world.txt"
```

**バックスラッシュ `\` でエスケープする**

```console:\でエスケープ
$ find . hello\ world.txt
```


## 検索式

`$ find` コマンドの検索式はやや特殊な構文となっている。

| 検索式 | 意味 |
|:-|:-|
| [`-name`](#-name) | ファイル名 |
| [`-type`](#-type) | ファイルの種類<br>`f`：ファイル<br>`l`：シンボリックリンク<br>`d`：ディレクトリ|
| `-uid` | ファイル所有者の UID |
| `-user` | ファイルを所有するユーザ名、ユーザ ID |
| `-print` | 検索結果を標準出力として出力|
| [`-atime`](#-atime) | 最終アクセス時刻（日単位） |
| [`-amin`](#-amin) | 最終アクセス時刻（時間単位） |
| `-mtime` | 最終更新時刻 |
| [`-size`](#-size) | ファイルサイズ |
| [`-exec コマンド {} \;`](#-exec) | 一致したファイルが指定したコマンドの引数として `{}` に展開され、実行される<br>コマンドは 1 ファイルづつ実行されるため、ファイル数が多いとコマンドの実行回数も増えるため、処理が遅くなることがある |
| [`-exec コマンド {} +`](#-exec) | `+` を使うことで、ファイルを一度に処理する<br>引数をまとめて処理できるコマンド（`$ rm`、`$ ls`、`$ echo` など）に対して特に有効 |
| `-ok コマンド {} \;` | `-exec` と同じ<br>確認あり |

## `-name`

```console:特定の名前のファイルを検索
$ find 検索開始ディレクトリ -name ファイル名
```

```console:拡張子（.txt）を持つファイルを検索
$ find 検索開始ディレクトリ -name "*.txt"
```

## `-type`

```console:ファイルを検索
$ find 検索開始ディレクトリ -type f -name ファイル名
```

```console:ディレクトリを検索
$ find 検索開始ディレクトリ -type d -name ディレクトリ名
```


## `-atime`

```console:過去 1 日以内にアクセスされたファイルを検索
$ find 検索開始ディレクトリ -atime -1
```

```console:過去 1 日以前にアクセスされたファイルを検索
$ find 検索開始ディレクトリ -atime +1
```

## `-amin`

```console:過去1時間以内にアクセスされたファイルを検索
$ find 検索開始ディレクトリ -amin -60
```

## `-size`

```console:100MB以上のファイルを検索
$ find 検索開始ディレクトリ -size +100M
```

## `-exec`

`{}` には一致したファイルパスが展開される。

`\;` で終了した場合、`{}` はコマンドに対して 1 つずつ渡される。一致したファイル数が多い場合、処理速度は低速になることがある。

[`;`](https://qiita.com/AsahinaKei/items/22d9fae93cabfbf137ee#%E8%A4%87%E6%95%B0%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E7%B6%9A%E3%81%91%E3%81%A6%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B) はシェルで特別な意味（コマンドの連続実行）を持つため、`\` でエスケープする必要がある。

```console:条件に一致したファイルを削除する（一つずつ実行）
$ find 検索開始ディレクトリ 検索式 -exec rm {} \;
```

一方、`+` で終了した場合、コマンドに対して `{}` はまとめて渡される。

指定するコマンドは引数をまとめて処理できるコマンド（`$ rm`、`$ ls`、`$ echo` など）である必要がある。

```console:条件に一致したファイルを削除する（まとめて実行）
$ find 検索開始ディレクトリ 検索式 -exec rm {} +
```

## `-perm`

パーミッションを指定して検索を行う。

指定方法が 3 つある。

- 完全一致
    - `-perm xxxx`
    - 例：`-perm 6000`　→　`6000` のみ該当
- AND 一致
    - `-perm -xxxx`
    - 例：`-perm -6000`　→　`4xxx` かつ `2xxx`　→　`6xxx` が該当
- OR 一致
    - `-perm /xxxx`
    - 例：`-perm /6000`　→　`4xxx` または `2xxx` または `6xxx` が該当

```console:指定したパーミッション条件に一致したファイルを検索する
$ find 検索開始ディレクトリ -perm パーミッション条件
```

# `$ locate`

ファイルを検索するためのコマンド。

事前に作成されたデータベースを使って検索を行うため、`$ find` よりも高速に動作する。

システム全体から検索を行う。ディレクトリを限定した検索は行うことができない。

```console:ファイルを検索する
$ locate 検索ワード
```

# `$ updatedb`

`$ locate` が検索に使用するデータベース（`/var/lib/mlocate/mlocate.db`）は `$ updatedb` によって手動で更新することができる。

ディストリビューションによってはデータベースは [`cron`](https://qiita.com/AsahinaKei/items/bac9cc198f7984987832#cron) によって定期的に更新される。

```console:データベースを更新する
$ sudo updatedb
```