3

ここで少し謎を解こうとしています... cron 経由で呼び出される gem を作成しました。

謎は次のとおりです。これはマシン上では機能しますがA、マシン上では機能しませんB。私が知る限り、環境は同じです。

どちらのマシンも Mac OS X 10.6 です。

また、cron が最小限の環境で実行されることも理解しています。

crontab:

10 2 * * * /Users/michael/.rvm/gems/ruby-1.9.3-p194/bin/my_gem

マシン上のエラーBは次のとおりです。

/Users/michael/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:247:in `to_specs': Could not find my_gem-toolchain (>= 0) amongst [bigdecimal-1.1.0, io-console-0.3, json-1.5.4, minitest-2.5.1, rake-0.9.2.2, rdoc-3.9.4] (Gem::LoadError)
    from /Users/michael/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:256:in `to_spec'
    from /Users/michael/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems.rb:1231:in `gem'
    from /Users/michael/.rvm/gems/ruby-1.9.3-p194/bin/my_gem:22:in `<main>'

内容はこちら/Users/michael/.rvm/gems/ruby-1.9.3-p194/bin/my_gem

#!/Users/michael/.rvm/rubies/ruby-1.9.3-p194/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'my_gem-toolchain' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/
    version = $1
    ARGV.shift
  end
end

gem 'my_gem-toolchain', version
load Gem.bin_path('my_gem-toolchain', 'my_gem', version)

22 行目は次のとおりです。gem 'my_gem-toolchain', version

env以下は、両方のマシンで cron を使用して実行した場合の出力です。

SHELL=/bin/sh
USER=michael
PATH=/usr/bin:/bin
PWD=/Users/michael
SHLVL=1
HOME=/Users/michael
LOGNAME=michael
_=/usr/bin/env

これは、GEM_PATH設定されていないことに関係していると思います。ただし、マシンでは設定されていないようAGEM_PATH見えますが、すべてが機能しています。

ruby の仕組みについて理解を深めたいと思います。どうやら私はまだ何かが欠けているようです。

Aこれがマシン上では機能するのに、マシン上では機能しないのはなぜBですか?

4

1 に答える 1

2

RVM は、開発者が環境を維持するための優れたツールですが、本番環境では悪夢です。cron から何かを実行すると、実行環境を維持する目的で、たとえそれがたまたま開発マシン上の cron であったとしても、本質的には「本番環境」になります。

システム全体に gem をインストールし、インストール先を想定しないスクリプトから実行することをお勧めします。gem の依存関係が正しくインストールされ、バイナリが適切に処理されるように、gem を作成するためのすべてのベスト プラクティスに従っていることを確認してください。gem をビルドしたら、システム Ruby 経由でインストールして、 OS の Ruby インタープリターのデフォルトの場所にあるすべてのユーザーと、そのすべての依存関係がインストールされます。

ベスト プラクティスについては、 Rubygems のMake your own gem ガイドをご覧ください。

次に、RVM ディレクトリの代わりにシステム ruby​​ を使用して、結果の gem ファイルをインストールします。

rvm use system
gem install my-gem-1.0.0.gem

これにより、すべてのセットアップが完了し、cron からすべてのユーザーに対して問題なく実行できるようになります。おそらく、ホーム ディレクトリで RVM に依存する cron ジョブを実行したくないでしょう。

あなたの質問に具体的に答えるために、Aでは機能するがBでは機能しない理由がいくつかあります.1つのマシンにシステム全体でgemをインストールし、もう1つのマシンにRVMを介してインストールした場合、依存関係がインストールされた場所に影響します(システム-全体とホームディレクトリ内); 他のマシンに RVM さえ持っていない場合は、間違いなくそうです。Gem がその依存関係を適切に宣言していない可能性があります。そのため、マシン B にインストールしたときに、依存関係はそこにインストールされませんでしたが、開発中に手動でマシン A にインストールしました。両方に同じ gem がインストールされていて、ホーム ディレクトリが共有されていて、他のすべてが重複しているように見えますが、シェル構成の RVM マジックが両方で実行されていない可能性があります。別のユーザーかもしれませんが、したがって、異なる環境。根本的な原因が何であれ、方程式から RVM を取り除き、rubygems のガイドラインに従うだけで問題は解決します。

于 2013-01-24T01:29:14.467 に答える