#!/usr/bin/env ruby if ARGV.length < 3 puts "Usage: #{$0} LOGFILE PIDFILE command arg..." exit 1 end TIMEFORMAT = "%b %d %X" logpath = File.expand_path(ARGV.shift) log = File.open(logpath, 'a') pidpath = File.expand_path(ARGV.shift) name = File.basename(ARGV.first) prog = ARGV.shift if prog[0] == '.'[0] prog = File.expand_path(prog) end cmd = ([prog] + ARGV).join(' ') # IO.daemonize exit! 0 if fork Process.setsid exit! 0 if fork Dir.chdir('/') File.umask(0) STDIN.reopen '/dev/null', 'r' STDOUT.reopen logpath, 'a' STDERR.reopen logpath, 'a' File.open(pidpath, 'w') {|f| f.puts(Process.pid) } log.puts "#{Time.now.strftime(TIMEFORMAT)} #{File.basename($0)}[#{Process.pid}]: #{cmd}" log.flush while true io = IO.popen("#{cmd} 2>&1", "r+") {|io| pid = io.pid File.open("#{pidpath}.child", "w") {|f| f.puts(pid)} #ch = Process.detach(pid) while line = io.gets log.puts "#{Time.now.strftime(TIMEFORMAT)} #{name}[#{pid}]: #{line}" log.flush end Process.waitpid(pid) #ch.join } log.puts "#{Time.now.strftime(TIMEFORMAT)} --- restart ----" log.flush sleep 2 end