Skip to content

Instantly share code, notes, and snippets.

@beugley
Created October 1, 2015 16:26
Show Gist options
  • Save beugley/5bdfe9bdbc455b6c0223 to your computer and use it in GitHub Desktop.
Save beugley/5bdfe9bdbc455b6c0223 to your computer and use it in GitHub Desktop.
Python: start a process if it's not running, or if the process's timestamp is newer than the start time
'''This script will start a process if it's not already running, or if the
timestamp of the process file is newer than the start time.
'''
import sys
import os
import pwd
import subprocess
import re
import time
if len(sys.argv) != 2:
print "Usage: %s name" % sys.argv[0]
sys.exit(1)
name = sys.argv[1]
if not os.path.isfile(name):
print "ERROR: '%s' does not exist!" % name
sys.exit(1)
whoami = pwd.getpwuid(os.getuid())[0]
##
## Get the pid of the process. Returns empty string if it's not running.
##
def getPID():
ps_cmd = "/bin/ps -fwwu %s | /bin/grep %s | /bin/grep -v grep | " \
"/bin/awk '{print $2}' | /bin/grep -v %d" % \
(whoami, name, os.getpid())
pipe = subprocess.Popen(ps_cmd, stdout=subprocess.PIPE, shell=True)
PID = [p.strip('\n') for p in pipe.stdout.readlines()]
rc = pipe.wait()
return PID
##
## Get the starttime of a process in number of seconds since the epoch.
##
def proc_starttime(pid):
p = re.compile(r"^btime (\d+)$", re.MULTILINE)
m = p.search(open("/proc/stat").read())
btime = int(m.groups()[0])
clk_tck = os.sysconf(os.sysconf_names["SC_CLK_TCK"])
stime = int(open("/proc/%d/stat" % pid).read().split()[21]) / clk_tck
return btime + stime
##
## Start the process and return the PID.
##
def start():
log = name + ".log"
try:
os.unlink(log)
except:
pass
cmd = "/usr/bin/nohup %s >%s 2>&1 &" % (name, log)
subprocess.Popen(cmd, shell=True)
return(getPID())
PID = getPID()
if len(PID) == 0:
##
## The process is not running; start it now.
##
PID = start()
print "Started %s, pid %s" % (name, PID[0])
elif len(PID) == 1:
##
## The process is already running. If the file's timestamp is newer than
## the start time, then restart the process.
##
start_time = proc_starttime(int(PID[0]))
file_time = os.path.getmtime(name)
if start_time < file_time:
os.kill(int(PID[0]),15)
PID = start()
print "Restarted %s, pid %s" % (name, PID[0])
else:
print "%s already running, pid %s" % (name, PID[0])
else:
print "WARNING: found %d instances of %s" % (len(PID), name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment