シバン (Unix)
(#! から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/08/10 09:34 UTC 版)
シバンまたはシェバン (英: shebang) とはスクリプトの#!
から始まる1行目のこと。起動してスクリプトを読み込むインタプリタを指定する。
シェバンやシバンと呼ばれるようになった理由については諸説あるが、一般的には、そこに書かれる2文字が「#」(ハッシュ、番号記号)と「!」(bang! バン (びっくりマーク)だから、ハッシュ・バン(hash bang)やシャープ・バン(sharp bang)と呼ばれるようになり、それを短く言う際に訛ってシェバンとなった、と説明されている。あるいは、もはもともとは主にシェルを起動していたからシェル・バン(shell bang)と呼ばれたと説明されることもある。いずれにせよ現在では、これらを縮めたシェバンという呼び方が一般的かつ簡素である[2]。日本の技術書ではシバンと3文字表記することも多い。
概要
シバンは基本的には、スクリプトを記述したファイルにおいて、スクリプトを実行するインタープリタのバイナリを指定するためのものである。
シバンが無かった時代には、スクリプトを実行させる場合、コマンドを書くたびにいちいち「インタープリタ名 + スクリプトのファイル名」を併せて書かなければならなかった。両方明記しなければスクリプトが動かないようでは、頻繁に実行する場合に特に煩わしい。シバンでインタープリタを指定できる仕組みを導入したことで、実行時にはファイル名だけを書けば済むようになった。
シバンを認識するのは、プログラムローダーである。つまり、オペレーティングシステム (OS) の execve
システムコール(exec
を参照)を処理するルーチン中のプログラムローダーである[注釈 1]。
プログラムローダーはファイルの1行目の最初に「#!」を見つけると、1行目の残りの文字列をインタープリタを指定しているものとして扱い、そのインタープリタにこのファイルのパスを渡す。するとそのインタープリタはこのファイルのデータを入力データ(実行すべきスクリプト)として扱い、それを実行する。
インタープリタはシバンを無視する。なぜならシバンの最初の文字は「#」であり、インタープリタにとって「#」は、その行がコメント文だということを意味するからである。
下のように1行目にシバンを書き、2行目以降にスクリプトの本文を書く。 Bourne shellのスクリプトだと下のようになる。
#!/bin/sh
echo 'Hello world!'
例
典型的な例をいくつか示す。
#! /bin/sh
- Bourn Shellでスクリプトを実行する。#! /bin/bash
- Bashでスクリプトを実行する。#! /usr/bin/pwsh
– PowerShellでスクリプトを実行する。#! /usr/bin/env python3
– Python3で、envプログラムを使いパスを探す。
注意点
- シバン行の最大文字数、指定可能な引数の数などは環境依存である。それを逸脱した場合の動作も環境依存である。特に複数個の引数を与えた場合にどう扱われるかはまちまち(普通に扱われる、2個目以降は無視される、空白の入った1個の引数にされる)であるため、注意が必要である[2]。
- ファイルの先頭がバイト順マークになっているUnicode形式のファイルの場合は動作しない。これはバイト順マークのために、OSのプログラムローダーがシバンを認識できなくなるためである。
envコマンドを使う手法
env
を使えるインタープリタがいくつかある。
Ruby言語のインタプリタ ruby
をenv
コマンドを用いて実行する場合だと、下のように書くことができる。
#!/usr/bin/env ruby
puts 'Hello world!'
ただし、envを用いる手法はPATH環境変数に依存する。親プロセスが独自にPATHを設定していた場合、想定外の動作をする可能性がある。ruby
インタプリタの場合は -x
オプションを利用した以下のようなシェルスクリプトに見せかけるトリックを使用したほうが良い。
#!/bin/sh</br> # -*- ruby -*-</br> exec ruby -x "$0" "$@"</br> #!ruby</br> puts 'Hello world!'</br>
他
- ラリー・ウォールのmetaconfigには、シバンを持たないシステムを検出し、スクリプトの先頭の<code>#!/bin/sh</code>を
: use /bin/sh
に置換する機能があった[注釈 2]
- ELFでは類似の機能として、プログラムヘッダの
INTERP
型エントリにインタプリタを記述することが出来る。ここには実行可能バイナリが使用する動的リンクライブラリのパス名を設定する。OSは実行可能バイナリと同時にインタプリタとして指定された動的リンクライブラリもロードして動的リンクの処理をさせる。 - FreeBSDのカーネルバイナリはインタプリタがカーネルでは使用されないことを逆手に取り、インタプリタとして
/red/herring
を指定している。[3]
注
- 注釈
- ^ システムコールではなく、ライブラリでエミュレートする実装も在った(SVR2ベースのEWS-UXなど)。この場合、スクリプトのsetuidやsetgidは無視される。
- ^ C Shellからスクリプトを実行された際に、Bourne Shellで実行させる為。
- 出典
- ^ 記事名の制約につき、記事名としての#記号は全角井桁
- ^ a b “The #! magic, details about the shebang/hash-bang mechanism”. www.in-ulm.de. 2022年11月23日閲覧。
- ^ “freebsd-src/sys/conf/kern.pre.mk at main · freebsd/freebsd-src”. GitHub. 2024年6月27日閲覧。 リンカへのオプションに
--dynamic-linker /red/herring
が含まれている。
- >> 「#!」を含む用語の索引
- #!のページへのリンク