バッチ処理をきっかけに、実行権限やOSの仕組みの理解が深まった話

## はじめに

バッチ処理の設定を通して、「処理が自動で実行される仕組み」がどのように成り立っているのかを改めて深掘りしてみました。

「ファイルの実行権限とは？」「ファイルを実行するとはどういうことか？」という疑問に対して深堀りを続ける中で、`umask` の存在や初期パーミッションの仕様、インタプリタとコンパイラの違い、さらにはシェルの役割など、点と点が線になってつながっていきました。この記事では、そうした疑問とその答えを順にたどっていきます。

---

## バッチ処理とは？

まず、「バッチ処理って結局なんなんだろう？」というところからスタートしました。

> OSに登録されたスケジュールに従って、特定の処理を自動で実行する仕組み

たとえば：

- 毎日深夜に古いログを削除する
- 毎週日曜にバックアップを取る

といった処理を、cronなどのスケジューラに登録することで、OSが決められた時間に自動で実行してくれます。

---

## ファイルの実行方法とシバン

cronに登録するスクリプトの書き方として、以下の2通りを見かけました。

```bash
/usr/bin/php /home/user/scripts/cleanup.php
```

と、

```bash
/home/user/scripts/cleanup.php
```

という形式です。

後者について「え？phpファイルを直接指定しても本当に動くの？」と疑問に感じたのがきっかけで、**シバン**の存在を知りました。

```php
#!/usr/bin/php
<?php
echo "Hello from cron!";
?>
```

ファイルの先頭に `#!` で始まる1行を記述しておくことで、「このファイルはこのプログラムで実行してね」とOSに伝えることができます。これにより、cronなどでファイルパスだけを指定しても実行可能になることが理解できました。

---

## 実行には実行権限が必要？

ここで新たな疑問が生まれました。

「ファイルに実行権限がないのに、これまで自分はプログラムを動かせていた。なぜ？」

たとえば、PHPファイルを `php script.php` として実行していたのに、ファイルに実行権限は必要なかったのです。では、なぜ `./script.php` のようにファイル名で直接実行しようとしたときに、実行権限が必要になるのでしょうか？

この疑問をきっかけに、「ファイルを実行するとはどういうことか」を深掘りしていきました。

---

## シェルの役割と実行の仕組み

まず理解しておくべきは、**シェルの役割**です。

シェルは、ユーザーの入力を解釈してOSに命令を伝えるインターフェースです。たとえば、ユーザーが `./script.php` と入力したとき、シェルは：

1. 該当ファイルに**実行権限があるかどうか**をチェックし、
2. シバンが書かれていれば、そこに指定された**インタプリタを呼び出してそのスクリプトを実行**します。

つまり、シェルは「このファイルをどう扱うか」「どのプログラムに渡すか」を決め、OSにその実行を依頼する仲介役を担っているということ。

---

## 実行権限がないファイルが動く理由

ここでようやく、なぜ実行権限がなくても `php script.php` のように実行できたのかが見えてきました。

実際に実行されているのは `php` コマンド（インタプリタ）であり、スクリプトであるphpファイルはその引数として読み込まれているだけです。つまり、**スクリプトには読み取り権限さえあればよく、実行権限は不要**なのです。

一方、ファイル名だけで実行する `./script.php` のようなケースでは、**OSがそのファイル自体をプロセスとして実行しようとする**ため、**実行権限（x）が必須**になります。

---

## umaskと初期パーミッション

`umask` について整理しておきます。

`umask` は、ファイルやディレクトリが作られたときに、どの権限を“引く”かを定めた設定です。

たとえば `umask 002` の場合：

| 種類 | 初期値 | umask適用後 |
| --- | --- | --- |
| ディレクトリ | 777 | 775 |
| ファイル | 666 | 664 |

新しく作成されたファイルには、最初から実行権限が**付与されない**ようになっています。

---

## 読み・書き・実行の意味の違い（ファイル vs ディレクトリ）

`rwx` の意味についても整理しておきます。

### ファイルの場合

| 権限 | 意味 |
| --- | --- |
| r | ファイル内容の読み取り |
| w | ファイルの編集・上書き |
| x | ファイルの実行 |

### ディレクトリの場合

| 権限 | 意味 |
| --- | --- |
| r | 中のファイル一覧を表示できる（ls） |
| w | ファイルの作成・削除ができる |
| x | ディレクトリに移動できる（cd） |

この違いを押さえておくと、`774` や `664` といったパーミッションの意味も明確になります。

---

## パーミッションの数値の意味（7, 6, 5, 4）

パーミッションを数値で指定する場合、`chmod 755` のような書き方をしますが、これらの数値には**2進数の意味**があります。

| 数値 | 2進数 | 対応する権限 |
| --- | --- | --- |
| 7 | 111 | rwx（読み・書き・実行） |
| 6 | 110 | rw-（読み・書き） |
| 5 | 101 | r-x（読み・実行） |
| 4 | 100 | r--（読みのみ） |

つまり、1ビットごとに権限を表しています。

---

## パーミッションの視覚化：774と664

| パーミッション | 所有者 | グループ | その他 |
| --- | --- | --- | --- |
| **774** | rwx | rw- | r-- |
| **664** | rw- | rw- | r-- |

774：所有者とグループは実行まで可能、その他は読み取りのみ。

664：誰も実行はできず、所有者とグループは読み書き可能、その他は読み取りのみ。

---

## インタプリタとコンパイル言語の違い

**インタプリタ言語とコンパイル言語の違い**も改めて整理しました。

### インタプリタ言語

インタプリタ（PHP, Pythonなど）は、**インタプリタ自体がファイルを読み取って処理する**ため、ファイルには**読み取り権限だけ**あれば動作します。

```bash
php myscript.php
```

これは、`php` コマンドが実行され、その中で `myscript.php` を読み取って実行するという流れです。

### コンパイル言語

一方で、Cなどのコンパイル言語は、事前に**バイナリファイル（実行可能ファイル）を生成**します。

```bash
gcc hello.c -o hello
./hello
```

このとき生成された `hello` には、**自動的に実行権限が付与されている**ことがほとんどです。

そのため、直接 `./hello` として実行することができます。

---

## ファイル単体で実行したい場合

インタプリタ言語でも、シェルスクリプトのように**ファイル名だけで実行**したい場合は次のようにします：

1. シバンを書く

```php
#!/usr/bin/php
<?php echo "Hello"; ?>
```

1. 実行権限を付ける

```bash
chmod +x myscript.php
```

こうすれば、`./myscript.php` のように直接実行できます。

---

## まとめ

今回の学びを通して、以下のようなことが理解できました：

- バッチ処理はスケジューラによって自動実行される
- ファイルを**名前で直接実行するには実行権限が必要**
- 一方で、インタプリタ経由で実行する場合は**読み取り権限のみでOK**
- umaskの仕様により、作成直後のファイルは実行不可なのがデフォルト
- 読み・書き・実行の意味はファイルとディレクトリで違う
- 数値によるパーミッション表記は2進数での権限の組み合わせを表している
- シェルは入力を解釈して、適切にファイルやプログラムの実行をOSに伝える役割を持っている
- コンパイルされたバイナリはビルド時に自動で実行権限が付く

最初は単なる「cronで実行されるスクリプト」だったものが、OSの中でどう扱われているのか、なぜ動くのかがだんだんと見えてきた感覚がありました。

---

## おわりに

この記事は、自分自身が「なぜ？」と疑問に思ったことをひとつずつ解きほぐして理解していった記録です。

同じように疑問を抱いた方にとって、少しでも理解のヒントになればうれしいです。

ご意見・フィードバック・指摘などあればぜひコメントで教えてください！