Rubyのシェバン
Twitterを見てたらmikutterのshebangの話が流れてきて,
@y_sni よくわかっていないのですが https://t.co/YpkomWWMxM こういうことだそうです
— Izumi Tsutsui (@tsutsuii) December 11, 2016
/usr/bin/ruby に Ruby がインストールされてない場合にも実行できるシェバンの話の奥が深かった。(今時, Rubyが/usr/bin/rubyじゃなくてホームディレクトリ以下に入ってる人も多そう)
#!/bin/sh exec ruby -x "$0" "$@" #!ruby p ARGV puts "Hello, World!"
実行するとまずシェルで実行されるじゃろ?
シェルで exec ruby -x "$0" "$@"
が呼ばれるじゃろ?
自身の #!ruby
以降の行がRubyインタプリタで実行されるじゃろ??
実行が終わったあとに次の行からのシェルスクリプトとしての実行はどうなるんじゃ??← exec コマンドはそのコマンドが実行した時点で終了するんでした
にわか知識じゃダメですね. はやく情報学群になりたい。
重要なのは, 3行目の #!ruby
はshebangとしては機能してなさそうだということです。
追記
タイトルを内容に即して 「シェバンがよくわからん」 から 「Rubyのシェバン」 に変えた。
./hoge.rb
で実行できることは理解できたが, ruby hoge.rb
でも実行できるんか疑問になった。
Rubyリファレンスマニュアル の記述は -x
オプションによって#!ruby
の行まで読み飛ばされているように読み取れる。
しかし実際はそうではなく, 先頭行にRuby以外のシェバンがあると, 常に #!ruby
の行まで読み飛ばされるらしい (じゃあ -x
って何やねん……)。一件落着。
これを利用するとRubyスクリプトなのにシェバンが異なることで実行できないファイルもつくることができ,
#!/bin/sh puts :hoge puts :hage puts :boke
を実行すると
ruby: no Ruby script found in input (LoadError)
と言われる。
昨夜はすっとぼけたことを言ってて,
@tsutsuii
— すに@地雷 (@y_sni) 2016年12月11日
-xオプションなしだとexec行もRubyスクリプトとして解釈されるようですが, execメソッドがRubyにもシェルと同様の挙動で定義されているので, 結局ruby -x で実行されるようですね。
これは間違い(シェバンを書いてないテストコードで誤解した。よく考えたらexecの引数がクォートで囲まれてないからRubyならundefined variable or methodを吐くはずだった) https://t.co/8vAQO0yqPl
— すに@地雷 (@y_sni) 2016年12月12日
早とちりは良くない。