Unix系OSでは、スクリプトの#!
から始まる一行目(shebangと呼ばれる)によって、起動するインタプリタを指定することができる。以下はWikipediaから拝借した例である。
#! /bin/sh
echo 'Hello world!'
このshebangにはOSによって制約があったり解釈がまちまちであったりといろいろと厄介なことが起こる。
- 本の虫 : Shebangという謎な事実上業界標準について
- Stack Overflow : how to use multiple arguments with a shebang (i.e. #!)?
- Stack Overflow : Perl: Shebang (space?) “#! ”?
- The #! magic, details about the shebang/hash-bang mechanism
それはさておき、Rubyを起動するには、
#! /usr/bin/ruby
puts 'Hello world!'
のように書かれるが、Rubyが/usr/bin/ruby
にあるとは限らない。システムによってはひょっとすると/usr/local/bin/ruby
にあるかもしれない。この問題を避けるために、しばしばenv
コマンドが使われる。
#! /usr/bin/env ruby
puts 'Hello world!'
これは大多数の環境で上手く動くと思われるが、しかし世の中には/usr/bin/env
が存在しないようなOSが存在する。(卜部昌平のあまりreblogしないtumblr : #!/usr/bin/env)
結論として、こんな風に書くと良いらしい。(Ruby 1.8.7 リファレンスマニュアル : Rubyの起動 )
#! /bin/sh
exec ruby -S -x "$0" "$@"
#! ruby
起動されたsh
は2行目のexec
でRubyに飛び、Rubyは3行目までを読み飛ばすという寸法である。
同じことをPythonでは以下のようにする。(effbot.org : How do I make a Python script executable on Unix?)
#! /bin/sh
""":"
exec python "$0" ${1+"$@"}
"""
__doc__ = """The above defines the script's __doc__ string. You can fix it by like this."""
sh
にとって2行目は:
なので無害、3行目のexec
でPythonに飛び、Pythonは2行目から4行目までを文字列リテラルとみなす、という塩梅である。
一方、Perl使いはこうした。(The Magic Perl Header)
#! /bin/sh
eval '(exit $?0)' && eval 'PERL_BADLANG=x;PATH="$PATH:.";export PERL_BADLANG\
;exec perl -x -S -- "$0" ${1+"$@"};#'if 0;eval 'setenv PERL_BADLANG x\
;setenv PATH "$PATH":.;exec perl -x -S -- "$0" $argv:q;#'.q
#!perl -w
+push@INC,'.';$0=~/(.*)/s;do(index($1,"/")<0?"./$1":$1);die$@if$@__END__+if 0
;#Don't touch/remove lines 1--7: https://pts.github.io/Magic.Perl.Header
追記 (2015/10/21)
上記のPythonの例はpep257に引っかかるようだ。なので、このチェックをすり抜けるようにしてみた。
#!/bin/sh
""":" .
exec python "$0" "$@"
"""
__doc__ = """
The above defines the script's __doc__ string. You can fix it by like this."""