シバン(shebang)とは、
UNIX系OSのスクリプトファイルの先頭行に記述される「#!」で始まる特別な行のことです。この行は、スクリプトを実行する際に使用する
インタプリタ(プログラム言語の処理系)を指定します。
シバンの役割
シバンは、スクリプトファイルが実行可能になった際に、OSがどの
インタプリタを使ってスクリプトを実行するかを指示する役割を持っています。これにより、スクリプトファイル自体が実行可能ファイルのように振る舞うことができます。
シバンの書き方
シバンは、`#!` に続けて
インタプリタのパスを記述します。以下はいくつかの例です。
Bourne Shellを使用する場合:
#!/bin/sh
echo 'Hello world!'
Rubyインタプリタを使用する場合(`env` コマンドを使用):
#!/usr/bin/env ruby
puts 'Hello world!'
Rubyインタプリタを使用する場合(`-x` オプションを使用):
#!/bin/sh
# -- ruby --
exec ruby -x "$0" "$@"
#!ruby
puts 'Hello world!'
シバンの仕組み
OSは、`execve` システムコールを通じてスクリプトを実行する際、ファイルの先頭行をチェックします。このとき、`#!` で始まる行をシバンとして認識し、その後に記述された
インタプリタを実行します。この処理は、プログラムローダーによって行われます。
注意点
バイト順マーク: ファイルがバイト順マーク付きの
Unicode形式である場合、OSはシバンを正しく認識できないため、スクリプトが正常に実行されないことがあります。
参照先: シバンの参照先は、実行可能なバイナリである必要があり、別のスクリプトファイルを参照することはできません。
引数: シバン行に指定できる
引数の数や最大文字数には環境依存性があり、過剰な
引数を与えるとエラーになる可能性があります。
`env` コマンド: `env` コマンドを利用したトリックは、`PATH`
環境変数に依存するため、環境によっては想定外の動作をすることがあります。
`env` コマンドのトリック
`#!/usr/bin/env ruby` のように `env` コマンドを使用すると、`PATH`
環境変数に登録されている `ruby` コマンドを検索して実行できます。これは、スクリプトの実行環境によって
Ruby のインストールパスが異なる場合に便利です。しかし、`PATH`
環境変数が変更されている場合は、異なるバージョンの
Ruby が実行される可能性や、
Ruby が見つからない可能性もあります。
その他の技術
metaconfig: ラリー・ウォールの metaconfig には、シバンを持たないシステムを検出し、スクリプトの先頭にシバンを挿入する機能がありました。
ELF: ELF形式の実行ファイルでは、プログラムヘッダの `INTERP` 型エントリに、
動的リンクライブラリのパス名を指定することで、類似の機能を実現しています。これにより、OSは実行ファイルと同時に、指定された
動的リンクライブラリをロードして、
動的リンクの処理を行います。
FreeBSD: FreeBSDのカーネルバイナリでは、
インタプリタとして `/red/herring` が指定されていますが、これはダミーであり、カーネルバイナリでは
インタプリタが使用されないことを逆手に取ったものです。
まとめ
シバンは、スクリプトの実行を自動化するための重要な仕組みです。シバンを正しく理解し使用することで、スクリプトの移植性や実行環境への依存性を低減することができます。ただし、環境依存性やバイト順マークなどの注意点も理解しておく必要があります。