はじめに
バッチ処理の設定を通して、「処理が自動で実行される仕組み」がどのように成り立っているのかを改めて深掘りしてみました。
「ファイルの実行権限とは?」「ファイルを実行するとはどういうことか?」という疑問に対して深堀りを続ける中で、umask
の存在や初期パーミッションの仕様、インタプリタとコンパイラの違い、さらにはシェルの役割など、点と点が線になってつながっていきました。この記事では、そうした疑問とその答えを順にたどっていきます。
バッチ処理とは?
まず、「バッチ処理って結局なんなんだろう?」というところからスタートしました。
OSに登録されたスケジュールに従って、特定の処理を自動で実行する仕組み
たとえば:
- 毎日深夜に古いログを削除する
- 毎週日曜にバックアップを取る
といった処理を、cronなどのスケジューラに登録することで、OSが決められた時間に自動で実行してくれます。
ファイルの実行方法とシバン
cronに登録するスクリプトの書き方として、以下の2通りを見かけました。
/usr/bin/php /home/user/scripts/cleanup.php
と、
/home/user/scripts/cleanup.php
という形式です。
後者について「え?phpファイルを直接指定しても本当に動くの?」と疑問に感じたのがきっかけで、シバンの存在を知りました。
#!/usr/bin/php
<?php
echo "Hello from cron!";
?>
ファイルの先頭に #!
で始まる1行を記述しておくことで、「このファイルはこのプログラムで実行してね」とOSに伝えることができます。これにより、cronなどでファイルパスだけを指定しても実行可能になることが理解できました。
実行には実行権限が必要?
ここで新たな疑問が生まれました。
「ファイルに実行権限がないのに、これまで自分はプログラムを動かせていた。なぜ?」
たとえば、PHPファイルを php script.php
として実行していたのに、ファイルに実行権限は必要なかったのです。では、なぜ ./script.php
のようにファイル名で直接実行しようとしたときに、実行権限が必要になるのでしょうか?
この疑問をきっかけに、「ファイルを実行するとはどういうことか」を深掘りしていきました。
シェルの役割と実行の仕組み
まず理解しておくべきは、シェルの役割です。
シェルは、ユーザーの入力を解釈してOSに命令を伝えるインターフェースです。たとえば、ユーザーが ./script.php
と入力したとき、シェルは:
- 該当ファイルに実行権限があるかどうかをチェックし、
- シバンが書かれていれば、そこに指定されたインタプリタを呼び出してそのスクリプトを実行します。
つまり、シェルは「このファイルをどう扱うか」「どのプログラムに渡すか」を決め、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など)は、インタプリタ自体がファイルを読み取って処理するため、ファイルには読み取り権限だけあれば動作します。
php myscript.php
これは、php
コマンドが実行され、その中で myscript.php
を読み取って実行するという流れです。
コンパイル言語
一方で、Cなどのコンパイル言語は、事前にバイナリファイル(実行可能ファイル)を生成します。
gcc hello.c -o hello
./hello
このとき生成された hello
には、自動的に実行権限が付与されていることがほとんどです。
そのため、直接 ./hello
として実行することができます。
ファイル単体で実行したい場合
インタプリタ言語でも、シェルスクリプトのようにファイル名だけで実行したい場合は次のようにします:
- シバンを書く
#!/usr/bin/php
<?php echo "Hello"; ?>
- 実行権限を付ける
chmod +x myscript.php
こうすれば、./myscript.php
のように直接実行できます。
まとめ
今回の学びを通して、以下のようなことが理解できました:
- バッチ処理はスケジューラによって自動実行される
- ファイルを名前で直接実行するには実行権限が必要
- 一方で、インタプリタ経由で実行する場合は読み取り権限のみでOK
- umaskの仕様により、作成直後のファイルは実行不可なのがデフォルト
- 読み・書き・実行の意味はファイルとディレクトリで違う
- 数値によるパーミッション表記は2進数での権限の組み合わせを表している
- シェルは入力を解釈して、適切にファイルやプログラムの実行をOSに伝える役割を持っている
- コンパイルされたバイナリはビルド時に自動で実行権限が付く
最初は単なる「cronで実行されるスクリプト」だったものが、OSの中でどう扱われているのか、なぜ動くのかがだんだんと見えてきた感覚がありました。
おわりに
この記事は、自分自身が「なぜ?」と疑問に思ったことをひとつずつ解きほぐして理解していった記録です。
同じように疑問を抱いた方にとって、少しでも理解のヒントになればうれしいです。
ご意見・フィードバック・指摘などあればぜひコメントで教えてください!