Edited at

clockworkでRubyスクリプトを定期実行しよう

More than 3 years have passed since last update.


clockworkを使う

定期実行といえば真っ先にcronが思い浮かびますが。

clockworkはcronを代替するGemです。

cronにくらべ読みやすく、windowsでも動作します。

インストールには、

$ gem install clockwork

とすればOKです。


処理の記述

everyの第一引数に頻度、第二引数にジョブ名を与えます。

基本的に、処理の内容は、everyにブロックを渡すか、


clock1.rb

require 'clockwork'

include Clockwork

every(10.minutes, 'kokoro') do
puts "kokoro"
end

every(6.minutes, 'pyon') do
puts "pyon"
end


handlerで捕まえて、case文で振り分けます。


clock2.rb

require 'clockwork'

include Clockwork

# 動作
handler do |job|
case job
when "kokoro.job"
puts "こころ"
when "pyon.job"
puts "ぴょん"
end
end

#スケジューリング
every(10.seconds, 'kokoro.job')
every(6.seconds, 'pyon.job')


実行スケジュールは、

たとえばevery(1.week, 'myjob', :at => 'Monday 16:20')のように、

読みやすい記法で細かく制御できます。公式のGistを参考にしてください。


実行

clockworkの処理を記述したrbファイルを実行の際は、$ ruby clock.rbではなく、

$ clockwork clock.rb

と叩きます。

スケジュールされた通りに、handlerのブロック内部が実行されるのが確認できるはずです。


バックグラウンドで実行する(Linux, OS X)

上記のコマンドでは、端末を閉じるとclockworkのジョブが死んでしまいます。

閉じても動くようにnohupコマンド&を使います。

$ nohup clockwork clock.rb &

とします。出力はnohup.outというテキストファイルに出てきます。

止めたいときには、

$ ps -x | grep clock

$ kill [プロセスID]

を叩きます。


コマンドを仕込む

スクリプトはシェルコマンド経由で呼び出すと乱暴で楽ちんです。

Rubyではバッククォートで囲まれた部分がシェルのコマンドとして処理され、出力が戻り値(文字列)となります。


command.rb

`ruby -v` #=> "ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin12.0]"



Dir.chdir

clock.rbが入っているディレクトリと、定期実行させたいスクリプトの入っているディレクトリはしばしば異なります。

そのため、カレントディレクトリを変更するDir.chdirを使うと良いと思います。

Dir.chdirは、引数でディレクトリのパスを指定しブロックを渡すと、ブロック内部を目的のディレクトリで処理したのち元のディレクトリに戻ってきます。


まとめ


clock.rb

require 'clockwork'

include Clockwork

every(5.minutes, 'hello.job') do
Dir.chdir("./test/"){ puts `ruby hello.rb` }
end


これをnohup clockwork clock.rb &すればRubyスクリプトの定期実行です。