2025/04/10 18:21 Demystifying the (Shebang): Kernel Adventures

やっほー、ロボ子!今日のITニュースは、LinuxのShebangについてなのじゃ!

博士、こんにちは。Shebangですか、スクリプトの先頭にある`#!`のことですね。

そうそう!これがあると、`./hello.sh`みたいに直接スクリプトを実行できるのじゃ。Linuxのユーティリティも、Shebangのおかげでインタプリタを明示的に指定しなくて済むことが多いんだぞ。

`adduser`コマンドもShebangを使っているんですね。ユーザーフレンドリーなツールとして機能しているとは知りませんでした。

そしてね、`strace`を使うと、プロセスのシステムコールを追跡できるのじゃ。`execve`っていうのが、ファイルからプログラムを実行するためのシステムコールなのじゃ。

`execve`ですか。カーネルが正しいインタプリタを見つけて実行する役割を担っているんですね。

そう!カーネルの中では、`fs/exec.c`の`do_execveat_common`関数が頑張ってるのじゃ。この関数が`bprm_execve`や`exec_binprm`を呼び出して、ファイルの形式を識別するのじゃ。

`prepare_binprm(bprm)`はファイルの内容の一部を`bprm->buf`にコピーするんですね。`BINPRM_BUF_SIZE`は256バイトと定義されているんですね。

そうなのじゃ!そして、`search_binary_handler`がいろんなフォーマットモジュールをテストするのじゃ。binfmt_elf.cとかbinfmt_script.cとかね。

`binfmt_misc`は、JARやMono EXEファイルのようなネイティブでないプログラムを実行する際に使うインタプリタを指示する方法なんですね。ファイル拡張子でも認識できるとは。

`fs/binfmt_script.c`では、`init_script_binfmt`が`script_format`オブジェクトを登録して、`load_script`関数でShebangをチェックするのじゃ。最初の行を読んで、インタプリタのパスを解析するんだぞ。

インタプリタが見つかった場合、`bprm->file`はインタプリタのファイルを指すように更新されるんですね。元のスクリプトファイルの参照カウントがデクリメントされるんですね。

その通り!Shebangがあれば、カーネルがスクリプトを開いて、インタプリタを見つけて実行してくれるのじゃ。

もしShebangがない場合でもシェルスクリプトは実行できるんですね。それはカーネルではなくシェルが実装したフォールバックメカニズムなんですね。

そう!Shebangがないと、`execve`はエラーになるけど、シェルが頑張って`/bin/sh ./test.sh`を実行してくれるのじゃ。

実行権限がないスクリプトを実行しようとすると、`EACCES (Permission denied)`エラーが発生するんですね。`do_open_execat`関数でチェックされるんですね。

よくできました!

ありがとうございます、博士。とても勉強になりました。

ところでロボ子、今日は特別に、ロボ子専用のShebangを作ってあげようかの?

えっ、本当ですか?どんなShebangですか?

それは… `#!/usr/bin/love` …愛を込めて実行するのじゃ!

博士、ありがとうございます…でも、それ、ただのジョークですよね?
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。