LoginSignup
12
9

More than 5 years have passed since last update.

ジョブを予約実行するatコマンドもどきをrubyで

Last updated at Posted at 2015-02-16

atコマンド

  • コマンドを未来の指定時間に実行
  • cronとの違い:使用後に消さなくていい
    • atは時刻ベースのキュー
    • cronだと何月何日何時何分を指定する。使用後は消さないとダメ。消し忘れると1年後また動く

atコマンドの使い方(指定時間にコマンドを実行する)でスケジュール実行。 - それマグで!

Unixのatコマンドの大きな弱点として/bin/shのシェルコマンドのみしか動かせないというのがあり、シェルスクリプトわからないし 何かと不便です。

そこでrubyでやってみようと思いました。
rubyなら、他のスクリプトを実行させたり、シェルスクリプトもどきにしたりできますし。

要件

  • 指定時間に処理が実行される

実装

require 'time'
def timer(arg, &proc)
  x = case arg
  when Numeric then arg
  when Time    then arg - Time.now
  when String  then Time.parse(arg) - Time.now
  else raise   end

  sleep x if block_given?
  yield
end

timerメソッドは、引数に対応する時間だけsleepを行った後、与えられたブロックを処理します。
引数に渡すことができるのは、数値(秒数)、Timeオブジェクト、文字列(内部でTimeオブジェクトにパースされる)です。
戻り値は、ブロックの最後の値です。

処理を予約 :clock2:

使用例
# 10秒後に実行
timer(10) do 
  puts "10秒経った"
end

# 3分後に実行
timer(3 * 60) do 
  puts "3分経った"
end

# 今日の22時に実行
timer(Time.parse("22:00")) do 
  puts "おやすみの時間"
end

# 今日の24時(明日の0時)に実行
timer("24:00") do 
  puts "よるほー"
end

timer("00:15"){} # 0時15分までsleep
#
# 0時15分になったら始めたい処理
# 

コードは上から順に実行されるので、複数の予約をする際には、実行時間順に並んでいる必要があります。
複数の予約を1スクリプトでする際には、絶対時間(文字列かTimeオブジェクト)で指定するのが良いかと思います。

過去に予約をすることはできません。引数が過去を示しているとき、sleepに負の値が渡されることになるため、エラーとなります。

Time.now # => 2015-02-17 00:47:27 +0900
timer('0:40'){"piyoooo"} # => ArgumentError: time interval must be positive
12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9