mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Ruby - Shebang ストリングによるスクリプト実行!

[ プログラミング ] [ Ruby ]

こんにちは。

Shebang(シバン、シェバン)ストリングを使用して Ruby スクリプトを実行する方法についての記録(&個人的方針)です。

どの方法を使用するかは個人の趣味・趣向によるところがあります。ご了承ください。

0. 前提条件

  • Linux Mint 17.1(64bit) での作業を想定。
  • Ruby 2.2.2-p95 での作業を想定。
  • Bash 4.3.33 での作業を想定。
  • Shebang ストリングとは?についてはここでは説明しない。
  • 以下の文書内に出現する「コマンドライン引数」以外の「引数」は Shebang 行の引数のことである。

1. env コマンドを使用する方法

これはよくある方法。

1
#! /usr/bin/env ruby
  • メリット
    • 環境に依存しにくい。(と一部で言われている。当然、環境に依存することも多々ある)
  • デメリット
    • OS によっては /usr/bin/env ではなく /bin/env であったり、当然 env コマンドそのものが存在しないこともあるため、実行できないことがある。
    • Shebang 行では引数が1個しか取得できない。(但し、取得できる引数の個数や文字数は OS により異なる)
      例えば ruby -v のように記述した場合、ruby コマンドと -v オプションではなく ruby -v というコマンドになってしまうということ。
      (個人的には Shebang 行で ruby コマンドに対するオプションを指定することはないが)
    • Linux 等で cron 実行する場合に環境変数 PATH を引き継がないため、 cron スクリプト内で PATH を適切に設定する必要がある。
    • top, ps コマンド等でプロセスの実行状況を確認するとプロセス名がスクリプト名でなく ruby になってしまうため、シェルスクリプトによるプロセス管理(二重起動防止等)が困難。

2. ruby コマンドをフルパスで指定する方法

これもよくある方法。

1
#! /usr/local/bin/ruby
  • メリット
    • Linux 等の cron で環境変数 PATH を意識する必要がない。
    • top, ps コマンド等でプロセスの実行状況を確認するとプロセス名がスクリプト名になるため、シェルスクリプトによるプロセス管理(二重起動防止等)が容易。(前項や次項の方法では困難)
  • デメリット
    • 環境に合わせて ruby コマンドをフルパスで指定する必要がある。
    • Shebang 行では引数が1個しか取得できない。(但し、取得できる引数の個数や文字数は OS により異なる)
      例えば ruby AAA BBB のように記述した場合、AAABBB という引数ではなく AAA BBB という引数になってしまうということ。
      (個人的には Shebang 行で ruby コマンドに対するオプションを指定することはないが)

3. Ruby リファレンスマニュアルで紹介されている方法

(Ruby リファレンスマニュアルの「Rubyの起動」で紹介されている方法)

1
2
3
#! /bin/sh
exec ruby -S -x $0 "$@"
#! ruby

まず、上記の各種オプションについて。

  • $0 はスクリプト自身、 $@ はコマンドライン引数の配列を表すシェル特殊変数。
  • -S は、 $0 がフルパスを含まない場合に必要に応じて環境変数 PATH を使用してスクリプトを探す ruby コマンドのオプション。
  • -x は、 #! で始まり ruby 文字列を含む行までを読み飛ばすための ruby コマンドのオプション。

そして、メリットとデメリット。

  • メリット
    • 環境に依存しにくい。(上記 1 の「env コマンドを使用する方法」よりは。但し、環境に依存することもある)
  • デメリット
    • 3行必要になる。
    • Shebang で ruby コマンドにオプションを付加することはできない。(実際にそういう局面はあまりないと感じているが)
    • Linux 等で cron 実行する場合に環境変数 PATH を引き継がないため、 cron スクリプト内で PATH を適切に設定する必要がある。
    • top, ps コマンド等でプロセスの実行状況を確認するとプロセス名がスクリプト名でなく ruby になってしまうため、シェルスクリプトによるプロセス管理(二重起動防止等)が困難。

4. 所感

当方は以下の理由で、上記 2 の「ruby コマンドをフルパスで指定する方法」に統一している。(プライベートでは)

  1. Linux サーバで cron 実行することが多い。
  2. Linux サーバも Linux クライアント環境も、メインで使用する Ruby をソースビルドで “/usr/local/bin/ruby” にインストールしている。
  3. 前項 2 により、クライアント側で作成した Ruby スクリプトが、そのままサーバ側で環境変数 PATH に注意を払わずに cron 実行できる。

また、ブログ等で Ruby スクリプトを公開する際も「ruby コマンドをフルパスで指定する方法」に則って記述したものに(ほぼ)統一している。
「環境に全く依存しない記述方法はないので、利用する側が自分の環境に合わせて適宜対応すべきである」という意味も込めて。

5. 参考サイト


他にも方法(よい方法)があるかもしれません。また気がついたら記事にします。

以上。

Comments