LoginSignup
175
162

More than 1 year has passed since last update.

Perl, Python 及び Ruby スクリプトにおける正しいshebangの書き方

Last updated at Posted at 2014-06-21

Unix系OSでは、スクリプトの#!から始まる一行目(shebangと呼ばれる)によって、起動するインタプリタを指定することができる。以下はWikipediaから拝借した例である。

example1.sh
#! /bin/sh
echo 'Hello world!'

このshebangにはOSによって制約があったり解釈がまちまちであったりといろいろと厄介なことが起こる。

それはさておき、Rubyを起動するには、

example1.rb
#! /usr/bin/ruby
puts 'Hello world!'

のように書かれるが、Rubyが/usr/bin/rubyにあるとは限らない。システムによってはひょっとすると/usr/local/bin/rubyにあるかもしれない。この問題を避けるために、しばしばenvコマンドが使われる。

example2.rb
#! /usr/bin/env ruby
puts 'Hello world!'

これは大多数の環境で上手く動くと思われるが、しかし世の中には/usr/bin/envが存在しないようなOSが存在する。(卜部昌平のあまりreblogしないtumblr : #!/usr/bin/env)

結論として、こんな風に書くと良いらしい。(Ruby 1.8.7 リファレンスマニュアル : Rubyの起動 )

example3.rb
#! /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?)

example.py
#! /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)

example.pl
#! /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に引っかかるようだ。なので、このチェックをすり抜けるようにしてみた。

example2.py
#!/bin/sh
""":" .

exec python "$0" "$@"
"""

__doc__ = """
The above defines the script's __doc__ string. You can fix it by like this."""
175
162
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
175
162