cron
and ruby
Do recurring operation with cron
is very suitable to do recurring events on e.g. a server. But what if you want do an recurring event with a certain minimal interval in a desktop machine which isn't running all the time.
A backup script is a typical use case where you want to run the operation if a certain time has passed since the last the last time the operation executed.
The idea is to call a script regularly with cron (e.g. every 10 minutes). The script keeps track on when the operation was called last time and only execute the operation again if a minimal set interval has passed.
A simple implementation has been made in ruby
below.
#!/usr/local/bin/ruby
require 'date'
require 'digest'
require 'tmpdir'
def command_tmp_file(command)
return "#{Dir.tmpdir}/last-call-#{Digest::MD5.hexdigest command.join("")}.date"
end
def set_last_time(command)
fname = command_tmp_file(command)
open(fname, 'w') { |f|
f.puts DateTime.now.rfc3339()
}
end
def seconds_since_last_time(command)
fname = command_tmp_file(command)
unless File.exists? fname then return -1 end
return Time.now.to_i - DateTime.rfc3339(File.read(fname)).to_time.to_i
end
def print_help
puts "Call \"wrapped\" command only if a minumum time (seconds) has passed since it was last executed"
puts "This utility may be called periodically (e.g. from cron) to achieve periodic execution"
puts "Usage: #{$0} INTERVAL COMMAND [ARGS]"
puts "Example: #{$0} 60 echo \"one minute since last call\""
end
if (ARGV.size < 2) || (not ARGV[0] =~ /^[0-9]+$/)
print_help
exit
end
command = Array.new(ARGV); command.shift
delay = seconds_since_last_time(command)
min_delay = ARGV[0].to_i
if delay == -1 || delay > min_delay
puts `#{command.join(" ")}`
set_last_time(command)
end
If this script is called multiple times the operation (echo "min 10 secs"
) is only executed if 10 seconds has passed since last time it (i.e. the wrapped operation) was executed.
$ ./interval.rb 10 echo "min 10 secs"
hello
$ ./interval.rb 10 echo "min 10 secs"
$ ./interval.rb 10 echo "min 10 secs"
hello
Is there an existing UNIX utility for this ...