Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env ruby
- raise "Requires your OS to support forking" unless Process.respond_to? :fork
- require 'chronic'
- require 'open3'
- include Open3
- # Usage
- if ARGV.empty? or ARGV[0] == '-h' or ARGV[0] == '--help'
- puts <<-USAGE
- Usage: every [TIME INTERVAL]: [COMMAND]
- Where: [TIME INTERVAL] is a natural language expression of time
- [COMMAND] is the command you wish to run
- Examples:
- # Delete a log file every five minutes
- every five minutes: rm /var/log/my_app.log
- # Restart nginx every morning
- every day at 1AM: /etc/init.d/nginx restart
- USAGE
- exit 0
- end
- # Validate and parse input
- index = ARGV.index { |arg| arg[-1] == ':' }
- raise "Parse error" if index.nil?
- time_str = ARGV[0..index].join(' ').chomp(':').strip
- command_str = ARGV[index+1..-1].join(' ').strip
- raise "Parse error" if command_str.nil? or command_str.empty?
- run_command = Proc.new do
- popen3 command_str do |stdin, stdout, stderr, wait_thread|
- status = wait_thread.value
- unless status.to_i == 0
- exit status.to_i
- end
- end
- end
- transform_time_str = Proc.new do
- if time_str.include? 'day'
- time_str.sub('day', 'tomorrow')
- else
- time_str + " from now"
- end
- end
- # Fork and process
- if pid = fork
- puts "Forked with pid #{pid}"
- Process.detach pid
- exit 0
- else
- $0 = "[every #{time_str}] #{command_str}"
- run_command.call
- loop do
- next_run = Chronic.parse(transform_time_str.call)
- if next_run.nil?
- exit 1
- end
- sleep 1 until Time.now >= next_run
- run_command.call
- end
- end
Add Comment
Please, Sign In to add comment