Prompt
シェバンにbash以外を指定する行為、
これ、やることある?
あはは!その疑問、Unix/Linuxの世界に足を踏み入れたばかりの頃は誰もが抱く「道しるべ」のようなものだね。
結論から言うと、シェバン(Shebang)に /bin/bash 以外を指定する行為は、「やることもある」 どころか、モダンな開発現場や特定の職種では 「日常茶飯事」 なんだ!
なぜ bash 以外を指定するのか、その熱い理由とバリエーションを、還元主義的な視点で解剖してみよう!
1. 他のシェル(zsh, sh, ksh)を指定する
OSや環境によって、標準のシェルが bash ではない場合があるんだ。
-
/bin/sh(POSIX sh): 「どのUnix系OSでも動く、最も最大公約数的なシェル」として書く時に使う。bash 特有の書き方(bashisms)を避け、移植性を高めたい時に指定するよ。 -
/bin/zsh: macOSの標準シェルだね。zsh特有の強力なグロブ(ファイル展開)や補完機能を使いたいスクリプトで指定される。
2. スクリプト言語を直接指定する(これが本命!)
実は、シェバンは「シェル」専用のものではないんだ。「実行ファイルであれば何でも指定できる」 というのがこの仕組みの真髄だよ。
-
Python:
#!/usr/bin/env python3 -
Perl:
#!/usr/bin/perl -
Ruby:
#!/usr/bin/ruby
これをしておくことで、python3 script.py と打たなくても、./script.py だけで Python スクリプトとして実行できるようになる。
「このファイルは Python という環境(インタプリタ)の上で動く、一つの独立したコマンドですよ」という宣言なんだね。
3. Rust や JavaScript すら指定できる!?
最近では、コンパイルが必要な言語や、Node.js のようなランタイムをシェバンに指定するのも珍しくないよ。
-
Node.js:
#!/usr/bin/env nodeフロントエンドエンジニアが、ちょっとしたビルドツールを自作する時によく使う。
-
Rust (rust-script): 君が学んでいる Rust でも、
rust-scriptのようなツールを使えば、シェバンに Rust を指定して「スクリプト感覚で Rust を実行する」なんて変態的でクールなこともできるんだ。
4. なぜ /bin/bash ではなく /usr/bin/env を使うのか?
ここで、情報工学的に重要な 「ベストプラクティス」 を一つ補足しておくね。
多くのプロフェッショナルなスクリプトは、#!/bin/python3 とは書かずに、 #!/usr/bin/env python3 と書くんだ。
-
理由: 実行ファイルの場所は OS によって微妙に違う(
/binだったり/usr/local/binだったり)。 -
envの役割:
envコマンドを経由することで、OS の PATH 環境変数 から目的のプログラムを探し出してくれる。これにより、環境が変わってもスクリプトが動く確率がグンと上がるんだ。
豆知識:シェバンは「カーネル」が読んでいる
これ、意外と見落とされがちだけど、シェバンの #! を解釈しているのは、シェルではなく OSのカーネル 自体なんだ(Linuxなら execve システムコールの中)。
カーネルがファイルの先頭2バイトを見て、「あ、これはプログラムを直接実行するんじゃなくて、指定されたインタプリタに渡すべきデータだな」と判断して、裏側でコマンドを書き換えて実行してくれているんだよ。
「シェルスクリプト = bash」という固定観念を壊すと、「単なるテキストファイルを実行可能なコマンドに変身させる魔法」 としてのシェバンの面白さが見えてくるはずだ。
君が Ubuntu サーバーで動かしている自作ツールがあるなら、試しに Python や Node.js でシェバンを書いて、実行権限(chmod +x)を与えて動かしてみてごらん。世界が広がるよ!
次は、Rust を使って「スクリプトのように動くバイナリ」を作る方法や、Makefile との使い分けについて深掘りしてみる?それとも、もっと OS 寄りのカーネルの話にする?
Would you like me to show you a specific example of a Rust script using a shebang?