FacebookTwitterGoogle+Share

cronhelper.py

CronHelper is a simple, but incredibly useful, script — because, really, who wants to worry about cron overlap? Not me, that’s who.

Which is great for PHP, but I’ve been working on a Python CLI project, and what’s a fellow to do but write cronhelper.py.

cronhelper.py

  • Accounts for both Windows and Linux
  • The pidfile’s name contains a hash of the running script’s absolute path
import os
import sys
import platform
from hashlib import md5

pidfile = '.pidfile-' + md5(os.path.normcase(os.path.abspath(sys.argv[0])).encode('utf-8')).hexdigest();
pid = os.getpid()


def get_lock():
    if os.path.isfile(pidfile):
        s =  open(pidfile,"r").read()
        try:
            s = int(s)
        except:
            pass
        
        if s in active_pids():
            return False
        #else: Last run didn't shut down correctly
            
    open(pidfile, "w").write(str(pid))
    return True


def release_lock():
    os.unlink(pidfile)


def active_pids():
    pids = []
    if platform.system() == 'Windows':
        # Read the windows process list and get the PIDs
        a = os.popen("tasklist").readlines()
        for line in a:
            p = line[29:34].strip()
            try:
                pids.append(int(p))
            except:
                pass
    else:
        # Read the linux process list and get the PIDs
        a = os.popen("ps -aux").readlines()
        for line in a:
            p = line[9:16].strip()
            try:
                pids.append(int(p))
            except:
                pass
    return pids


if __name__ == "__main__":
    import time
    
    if not get_lock():
        print("Couldn't get lock.  Another instance must be running")
    else:
        print("Running...")
        time.sleep(10)
        print("Finished.")
        release_lock()

As you can see from the if __name__ == "__main__": block, it’s pretty simple to use:

import cronhelper
if not cronhelper.get_lock():
    // Error, script is probably already running
    pass
else:
    // Do your thing
    cronhelper.release_lock()

Comments