シバンまたはシェバン () とはスクリプトの#!から始まる1行目のこと。起動してスクリプトを読み込むインタプリタを指定する。
シェバンやシバンと呼ばれるようになった理由については諸説あるが、一般的には、そこに書かれる2文字が「#」(ハッシュ、番号記号)と「!」(bang! バン (びっくりマーク)だから、ハッシュ・バン(hash bang)やシャープ・バン(sharp bang)と呼ばれるようになり、それを短く言う際に訛ってシェバンとなった、と説明されている。あるいは、もはもともとは主にシェルを起動していたからシェル・バン(shell bang)と呼ばれ、それが訛ったと説明されることもある。いずれにせよ現在では、これらを縮めたシェバンという呼び方が一般的かつ簡素である。日本の技術書ではシバンと3文字表記することも多い。
概要 シバンは基本的には、スクリプトを記述したファイルにおいて、スクリプトを実行するインタプリタのバイナリを指定するためのものである。
シバンが無かった時代には、スクリプトを実行させる場合、コマンドを書くたびにいちいち「インタプリタ名 + スクリプトのファイル名」を併せて書かなければならなかった。両方明記しなければスクリプトが動かないようでは、頻繁に実行する場合に特に煩わしい。シバンでインタプリタを指定できる仕組みを導入したことで、実行時にはファイル名だけを書けば済むようになった。
シバンを認識するのは、プログラムローダーである。つまり、オペレーティングシステム (OS) の execve システムコール(exec を参照)を処理するルーチン中のプログラムローダーである。
プログラムローダーはファイルの1行目の最初に「#!」を見つけると、1行目の残りの文字列をインタプリタを指定しているものとして扱い、そのインタプリタにこのファイルのパスを渡す。するとそのインタプリタはこのファイルのデータを入力データ(実行すべきスクリプト)として扱い、それを実行する。
インタプリタはシバンを無視する。なぜならシバンの最初の文字は「#」であり、インタプリタにとって「#」は、その行がコメント文だということを意味するからである。
1行目にシバンを書き、2行目以降にスクリプトの本文を書く。Bourne Shellのスクリプトだと以下のようになる。
#!/bin/sh echo 'Hello world!'
例 典型的な例をいくつか示す。 #!/bin/sh - Bourne Shellでスクリプトを実行する。 #!/bin/bash - Bashでスクリプトを実行する。 #!/usr/bin/pwsh – PowerShellでスクリプトを実行する。 #!/usr/bin/env python3 – Python 3で、envプログラムを使いパスを探す。
注意点
シバン行の最大文字数、指定可能な引数の数などは環境依存である。それを逸脱した場合の動作も環境依存である。特に複数個の引数を与えた場合にどう扱われるかはまちまち(普通に扱われる、2個目以降は無視される、空白の入った1個の引数にされる)であるため、注意が必要である。 ファイルの先頭がバイト順マークになっているUnicode形式のファイルの場合は動作しない。これはバイト順マークのために、OSのプログラムローダーがシバンを認識できなくなるためである。
envコマンドを使う手法 envを使えるインタプリタがいくつかある。
Ruby言語のインタプリタ ruby をenv コマンドを用いて実行する場合だと、以下のように書くことができる。
#!/usr/bin/env ruby puts 'Hello world!'
ただし、envを用いる手法はPATH環境変数に依存する。親プロセスが独自にPATHを設定していた場合、想定外の動作をする可能性がある。ruby インタプリタの場合は -x オプションを利用した以下のようなシェルスクリプトに見せかけるトリックを使用したほうが良い。
#!/bin/sh # -*- ruby -*- exec ruby -x "$0" "$@" #!ruby puts 'Hello world!'
Java Java 11以降はシバンがサポートされ、Java 25以降はコンパクトソースファイルがサポートされたため、以下のコードで動作する。ただし、ファイル名は拡張子 .java を付けてはならない。
#!/usr/bin/java --source 25 void main() { IO.println("Hello, World!"); }
他 ラリー・ウォールのmetaconfigには、シバンを持たないシステムを検出し、スクリプトの先頭の#!/bin/shを: use /bin/shに置換する機能があった
ELFでは類似の機能として、プログラムヘッダのINTERP型エントリにインタプリタを記述することが出来る。ここには実行可能バイナリが使用する動的リンクライブラリのパス名を設定する。OSは実行可能バイナリと同時にインタプリタとして指定された動的リンクライブラリもロードして動的リンクの処理をさせる。 FreeBSDのカーネルバイナリはインタプリタがカーネルでは使用されないことを逆手に取り、インタプリタとして/red/herringを指定している。 リンカへのオプションに--dynamic-linker /red/herringが含まれている。
歴史 シバンは、ベル研究所のデニス・リッチーにより、Version 7 Unix(Unix 第7版)とVersion 8(Research Unix)の間の時期に導入された。また、カリフォルニア大学バークレー校のコンピューター科学研究グループによるBSDのリリースにも追加されており、2.8BSD には存在し、4.2BSD ではデフォルトで有効になっていた。ベル研究所の Version 8 Unix 以降の版は一般公開されなかったため、シバンが人々に広く知られるようになった最初の例はBSDとなった。
Version 7 シバンの一歩手前の段階。
インタプリタ指示子無しで、シェルスクリプトをサポートする、というやり方は1979年の Version 7 Unix のドキュメントに見られる。その説明によると、Bourneシェルの機能が実行権限を与えられたファイルを特別なものとして扱い、スクリプトの冒頭に「:」や「#」など特定の文字がある場合に、シェルがサブシェルを起動し、そのファイル内のコマンドを解釈・実行するという仕組みであった。 この方式では、スクリプトはBourneシェル内から呼び出されたときにのみ、通常のコマンドのように動作した。オペレーティングシステムの exec() システムコールを通じて直接スクリプトファイルを実行しようとしても失敗する仕様になっていたため、スクリプトは通常のシステムコマンドのように一貫して動作することはできなかった。
Version 8 「Unix第8版」(Version 8 Unix。Research Unix)以降では、スクリプトと実行ファイルの扱いが異なる問題は解消された。デニス・リッチーは、1980年1月のメールで、Unix第8版向けにインタプリタ指示子のサポートをカーネルに導入したことについて説明した。
以下、上記の翻訳。
脚注
注釈
出典