スクリプトの先頭行に書かれている #!/bin/sh
の事を shebang (シェバング) と呼びます。
古くはプログラムが実行された際にローダがファイルの先頭 2 バイトを参照してファイルの形式を調査した事に由来しているらしく、例えば FreeBSD や Linux の最近の実行可能ファイルであれば 7f45(16) になっています (その後 4c46(16) と続いているので、ファイルをダンプすると ELF と読めます)。
ファイル先頭のこの値の事を magic number とも呼び、初期の file(1) コマンドはこの magic number を読み取ってファイルの種類を報告していたそうです (今の file(1) も基本は magic number を利用している筈です)。
shebang は通常はスクリプトを実行するインタプリタのパスを記述しますが、実は実行可能なプログラムであればインタプリタ以外も記述できるので、あるプログラムの設定ファイルの先頭にプログラム名自身を書いておくとその設定でプログラムが実行できて実は便利です。
例えば sshd(8) を /usr/local/etc/sshd/mysshd.conf を設定ファイルとして起動したい場合、
# /usr/sbin/sshd -f /usr/local/etc/sshd/mysshd.conf
通常はこの様に起動します。
ところが設定ファイル /usr/local/etc/sshd/mysshd.conf の先頭に shebang として #!/usr/sbin/sshd -f を追加して /usr/local/etc/sshd/mysshd.conf に実行権限を与えると、設定ファイルを実行する事で sshd(8) が起動できるので便利です。
# cat /usr/local/etc/sshd/mysshd.conf
Port 20022
Protocol 2
:
# ex -s !$ <<- EOF
ex -s /usr/local/etc/sshd/mysshd.conf <<- EOF
> 0i
> #!/usr/sbin/sshd -f
> .
> w!
> EOF
# head !$
head /usr/local/etc/sshd/mysshd.conf
#!/usr/sbin/sshd -f
Port 20022
Protocol 2
:
# chmod 755 !$
chmod 755 /usr/local/etc/sshd/mysshd.conf
# !$
/usr/local/etc/sshd/mysshd.conf
# netstat -anf inet | egrep '^Active|^Proto|\.20022'
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 *.20022 *.* LISTEN
この実行例では /usr/local/etc/sshd/mysshd.conf の先頭1行目に shebang を挿入するために ex(1) をヒアドキュメントと共に利用していますが、ex(1) は中身は vi(1) と同じですのでこの使い方を覚えておくと何かと便利です。
一時期 shebang に #!/usr/bin/env
を記述する方法が一部で流行した様ですが個人的には絶対にお勧めしません。
env(1) は実行している環境に影響を受けるので、異なる環境で実行した場合にインタプリタが変わってしまう可能性があり、動作が一意に決定できない危険性があるからです。
例えば個人の環境で開発したスクリプトを cron(8) に設定した際にインタプリタが異なってしまい動作しなくなった等の実例が沢山あります。
以前別な投稿でも書きましたがスクリプト内部で利用するコマンドはフルパスで指定した方が良いと思います。