[Server & Network General] crontab: ruby スクリプトを実行する

rvm + zsh 環境で、設定してみます。

このあたりで復習しつつ、設定を進めます。

公式の手順に従う

後述の通り、いろいろ試してはまりました。
こちらのエントリに救われました。

  1. cron にはシェルスクリプトを登録する。
  2. シェルスクリプト内で、rvm 環境をロードする。
  3. シェルスクリプト内で、ruby スクリプトを実行する。

シェルスクリプトを用意する

まず、そのままの状態で何が呼ばれるのか確認してみました。

blog_mysql.sh
#!/usr/bin/zsh
#ruby $HOME/sbin/blog_mysql.rb
ruby -v
echo $PATH
$ chmod 700 sbin/blog_mysql.sh

cron を1分ごとに動かしながら確認します。

crontab
SHELL=/usr/bin/zsh
MAILTO='alert@exsample.com'
HOME='/home/****'
* * * * *  $HOME/sbin/blog_mysql.sh

実行結果。rvm 環境は読み込まれていないことが分かります。

ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]
/usr/bin:/bin

シェルスクリプトに rvm 環境を読み込みむ

以下の2行を加えます。

# load rvm ruby
source $HOME/.rvm/environments/default

実行結果。成功です。

ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]
/home/****/.rvm/gems/ruby-2.1.0/bin:/home/****/.rvm/gems/ruby-2.1.0@global/bin:/home/****/.rvm/rubies/ruby-2.1.0/bin:/usr/bin:/bin

設定

実行したい ruby スクリプトを指定、crontab を修正して完了。

blog_mysql.sh
#!/usr/bin/zsh
# load rvm ruby
source $HOME/.rvm/environments/default
ruby $HOME/sbin/blog_mysql.rb

作ったスクリプトを設定してみます。

実行結果。

default: 0
osi: 0
gfm: 0

完了。

補遺

遭遇したエラーとか含め、ログとして残しておく。

cron から ruby への path を通してみる

レンタルサーバは rvm で ruby が入っているようで、crontab 内で path をどう指定するか分からない。
.rvm 以下を探って、ココをあててみることにする。

$ .rvm/rubies/default/bin/ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]

こちらを参考に cron から呼べるように調整します。

$ crontab -e
crontab
MAILTO='alert@exsample.com'
HOME='/home/****'
RUBY_PATH='.rvm/rubies/default/bin'
* * * * *  $HOME/$RUBY_PATH/ruby -v >> $HOME/ruby_version
$ tail ruby_version -fruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]

OKです。

gem が require できないとエラー

ということで、ココで作ったスクリプトを設定してみます。

と思ったら、cron deamon からエラーが出てました。

/home/****/.rvm/rubies/ruby-2.1.0/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- mysql (LoadError)
        from /home/****/.rvm/rubies/ruby-2.1.0/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /home/****/sbin/blog_mysql.rb:1:in `<main>'

gem の require でこけているようです。
path を追加すればできそうですが、rvm の知識がなさ過ぎてできませんでした。

crontab 内で cd してみる

気を取り直して調べ直してみました。
シェルスクリプトで、cd /foo && ruby bar のようなことができるよう。

crontab
MAILTO='alert@exsample.com'
HOME='/home/****'
* * * * *  cd $HOME && ruby sbin/blog_mysql.rb

odd number list for Hash

エラーが発生。

sbin/blog_mysql.rb:7: odd number list for Hash
  default: "SELECT count(*) FROM wp_post...
          ^
sbin/blog_mysql.rb:7: syntax error, unexpected ':', expecting '}'
  default: "SELECT count(*) FROM wp_post...
          ^
sbin/blog_mysql.rb:7: syntax error, unexpected ',', expecting $end

どうもレンサバ標準の ruby 1.8 が呼ばれているよう。
こんな形で調べたら、やっぱりそうでした。

* * * * *  ruby -v >> $HOME/ruby_version
ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]

ということで再度修正。

crontab
MAILTO='alert@exsample.com'
HOME='/home/****'
RUBY_PATH='.rvm/rubies/default/bin'
* * * * *  cd $HOME && $HOME/$RUBY_PATH/ruby sbin/blog_mysql.rb

gem が require できないとエラー

gem が require できないに戻りました。

/home/****/.rvm/rubies/ruby-2.1.0/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- mysql (LoadError)
        from /home/****/.rvm/rubies/ruby-2.1.0/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from sbin/blog_mysql.rb:1:in `<main>'

補遺