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

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

[markdown]

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

> * [Crontab: スクリプトを定期的に実行しログを残す | deadwood](https://www.d-wood.com/blog/2013/09/16_4644.html)

## 公式の手順に従う

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

> * [rvmのrubyをcrontabで実行する](http://technologyblog.lain003.info/users/1/blogs/73)
> * [RVM: Ruby Version Manager – Using Cron with RVM](https://rvm.io/integration/cron)

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

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

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

“`bash:blog_mysql.sh
#!/usr/bin/zsh
#ruby $HOME/sbin/blog_mysql.rb
ruby -v
echo $PATH
“`

“`prettyprinted
$ chmod 700 sbin/blog_mysql.sh
“`

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

“`bash:crontab
SHELL=/usr/bin/zsh
MAILTO=’alert@exsample.com’
HOME=’/home/****’
* * * * * $HOME/sbin/blog_mysql.sh
“`

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

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

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

以下の2行を加えます。

“`bash
# load rvm ruby
source $HOME/.rvm/environments/default
“`

実行結果。成功です。

“`prettyprinted
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 を修正して完了。

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

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

> * [gems: ruby-mysql, inifile – .my.cnf の設定をロードして、Ruby から MySQL へ接続する | deadwood](https://www.d-wood.com/blog/2014/01/18_5295.html)

実行結果。

“`prettyprinted
default: 0
osi: 0
gfm: 0
“`

完了。

## 補遺

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

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

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

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

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

> * [橋本商会 » crontabでrbenvのrubyを使う](http://shokai.org/blog/archives/7258)

“`prettyprinted
$ crontab -e
“`

“`bash:crontab
MAILTO=’alert@exsample.com’
HOME=’/home/****’
RUBY_PATH=’.rvm/rubies/default/bin’
* * * * * $HOME/$RUBY_PATH/ruby -v >> $HOME/ruby_version
“`

“`prettyprinted
$ 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 できないとエラー

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

> * [gems: ruby-mysql, inifile – .my.cnf の設定をロードして、Ruby から MySQL へ接続する | deadwood](https://www.d-wood.com/blog/2014/01/18_5295.html)

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

“`prettyprinted
/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 `


“`

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

### crontab 内で cd してみる

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

“`bash:crontab
MAILTO=’alert@exsample.com’
HOME=’/home/****’
* * * * * cd $HOME && ruby sbin/blog_mysql.rb
“`

#### odd number list for Hash

エラーが発生。

“`prettyprinted
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 – odd number list for Hash on very basic script – Stack Overflow](http://stackoverflow.com/questions/18032777/odd-number-list-for-hash-on-very-basic-script)

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

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

ということで再度修正。

“`bash: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 できないに戻りました。

“`prettyprinted
/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 `


“`

## 補遺

> * [cron上でのコマンド実行を再現する – Qiita](http://qiita.com/nog/items/0e9ab97cf59d82cdf6be?utm_source=Qiita%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9&utm_campaign=6d4e40afe7-Qiita_newsletter_106_28_5_2014&utm_medium=email&utm_term=0_e44feaa081-6d4e40afe7-32774809)
[/markdown]