FC2ブログ

blogaomu2.1はこの度、http://blogaomu.comに引っ越しました。最新の更新はblogaomu.comにて行なっておりますので、ブックマーク・RSS等の設定をお願い致します。

さくらインターネットのレンタルサーバーでcronからRubyプログラムを実行するときに躓いたのでメモ

こんにちは、こんにちわん!

さくらインターネットのレンタルサーバーでcronからRuby製twitter botを定期実行することができたので、備忘録を付けておきたいと思います。ちょっと躓いた点をつらつら書いていきます。
OSは FreeBSD 7.1-RELEASE-p15 i386 、Rubyのバージョンはruby 1.8.7 です。

コマンドラインからRubyスクリプトを実行できたんだけど、cronからではうまく実行できない罠


おはようござる!とツイートする以下のスクリプトを書きました。
~/wk/ohayougozaru/ohayougozaru.rb
#!/usr/local/bin/ruby

require 'rubygems'
require 'twitter_oauth'
require 'twitteruser.rb'

user = TwitterUser.new()

t = TwitterOAuth::Client.new({
:consumer_key => user.consumer_key,
:consumer_secret => user.consumer_secret,
:token => user.token,
:secret => user.secret
})

p t.authorized?
t.update 'おはようござる!'

twitteruser.rbにはconsumer_keyとかoauth用の設定が書かれています。
コマンドラインから実行するとこんな感じで正常に動作します。
$ ./ohayougozaru.rb
true
#この後「おはようござる!」とツイートされる

がしかし、cronから実行させるとツイートしてくれない。
cron実行後に送られてくるメールを見るとtwitter_oauth gemが無いっていわれています。おかしいなあ。gem list --local するとインストールされているんだけどな。
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- twitter_oauth (LoadError) 
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /home/hoge/wk/ohayougozaru/ohayougozaru.rb:4

ごにょごにょ調べていたら、環境変数が違ってるのかなと思い echo $GEM_HOME とか見たんですが、コマンドラインから正常に実行されるんだから間違ってないはず。

ということはcron側でおかしなことが起きているのかなと推測。google先生に聞いてみたらそれっぽい記事を発見!
さくらインターネット設定メモ - i123の日記
http://d.hatena.ne.jp/i123/20080921/1222002928

Rubyスクリプトをcronで実行しようとすると、postmaster宛に下記のメールが届いて実行されない。

test.rb:2:in `require': no such file to load -- rubygems (LoadError)

どうやら、自分でgem を使用してインストールしたものをrequireする場合は、環境変数を設定して

しなければならないらしい。そこで、サーバコントロールパネルの環境変数を設定する。


サーバーコントロールパネルから環境変数を設定するですと・・・!?
つまり、ブラウザからさくらサーバーの設定画面を開いてそこのcronの設定というページで環境変数RUBYLIBとGEM_HOMEを設定すればOK。
(エントリー書いてるとき冷静にログを見たらgemのライブラリが違うところを見ているのを発見。私の設定では、gemは/home/hoge/gems/以下にインストールされてそこを見に行くようにしていたのですが、なんで早く気付かなかったんだろうwww)

とりあえず設定して実行すると、先程とは違うメッセージが。一歩前進?
/home/hoge/gems/lib/rubygems/custom_require.rb:36:in `gem_original_require': no such file to load -- twitteruser.rb (LoadError) 
from /home/hoge/gems/lib/rubygems/custom_require.rb:36:in `require'
from /home/hoge/wk/ohayougozaru/ohayougozaru.rb:5

今度は、メインのスクリプトと同じディレクトリにあるtwitteruser.rbをrequireで呼び出そうとしたけど、そのファイルが無いよって言われています。

この話、最近見た覚えがあるなあ。
Rubyでrbファイルをrequireするときはドットを打つと良さそう - アインシュタインの電話番号☎
http://d.hatena.ne.jp/ruedap/20110531/ruby_require_load_path

こちらのエントリーの解決策2:ロードパスにカレントディレクトリを追加する を行ってみましたよ。
スクリプトはこうなりました。
#!/usr/local/bin/ruby
$:.unshift File.dirname(__FILE__) #この1行を追加

require 'rubygems'
require 'twitter_oauth'
require 'twitteruser.rb'
#(以下略)

これでうまくcronからbotを起動できました。パスが通ってなかったんですね。
cronでスクリプトを実行させるときのカレントディレクトリはユーザーホーム(/home/hoge hogeはユーザー名)なので、ロードパスかホームディレクトリにrequireで呼び出すファイルがなければエラーが起きてしまう。ということなんでしょう。

参考にしました。
組み込み関数 - Rubyリファレンスマニュアル require
http://www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFB4D8BFF4.html#require
組み込み関数 - Rubyリファレンスマニュアル $: $LOAD_PATH
http://www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFCAD1BFF4.html#a.24.3a

今回はさくらインターネットのレンタルサーバー特有(?)の事象なのかもしれませんが、他のサーバーでも似たような話はあるかもしれないので、頭の隅に入れておこうと思います。
めでたしめでたし。

追記 2011.7.3)
ユーザー情報取得の部分をpitに置き換えてみました。
blogaomu2.1: pitを使ってみたかった http://blogaomu21.blog91.fc2.com/blog-entry-182.html
スポンサーサイト



シェアはこちらからどうぞ

このエントリーをはてなブックマークに追加

コメントの投稿

非公開コメント

プロフィール

TAKAyuki_atkwsk

お知らせ
最新記事
最新記事のRSSフィード

最新コメント
最新トラックバック
カテゴリ
タグクラウド
月別アーカイブ
ブクログ
携帯百景