#!/usr/bin/python import os import pwd import sys import errno import subprocess def usage(retval): sys.stderr.write("Usage: %s --command command --string string\n" % sys.argv[0]) sys.exit(retval) def start_command(verbose, command, filename): if verbose: print('trying to start command') pid = os.fork() if pid == 0: try: exit_code = subprocess.call(command, shell=True) if exit_code != 0: sys.exit(exit_code) finally: os.unlink(filename) else: with open(filename, 'w') as file_: file_.write('%s\n' % pid) if verbose: print 'waiting...' dummy, exit_code = os.wait() if verbose: print 'returning...' return exit_code def pid_exists(verbose, pid): if subprocess.call('ps -p %d > /dev/null 2>&1' % pid, shell=True) == 0: if verbose: print('pid does exist') return True else: if verbose: print('pid does not exist') return False def get_just_one_dir(): #just_one_dir = os.path.join(os.environ['HOME'], '.just-one') uid = os.geteuid() pwent = pwd.getpwuid(uid) home_dir = pwent.pw_dir just_one_dir = os.path.join(home_dir, '.just-one') try: os.mkdir(just_one_dir, 0755) except (OSError, IOError): dummy, mkdir_extra, dummy = sys.exc_info() if mkdir_extra.errno == errno.EEXIST: pass else: raise return just_one_dir def main(): command = None string = None pid = None verbose = False while sys.argv[1:]: if sys.argv[1] == '--command': command = sys.argv[2] del sys.argv[1] elif sys.argv[1] == '--string': string = sys.argv[2] del sys.argv[1] elif sys.argv[1] == '--verbose': verbose = True elif sys.argv[1] in [ '--help', '-h' ]: usage(0) else: sys.stderr.write("%s: Unrecognized option: %s\n" % (sys.argv[0], sys.argv[1])) usage(1) del sys.argv[1] if not command: sys.stderr.write("%s: --command command is a required option\n" % sys.argv[0]) usage(1) if not string: sys.stderr.write("%s: --string string is a required option\n" % sys.argv[0]) usage(1) if verbose: print('about to mkdir') just_one_dir = get_just_one_dir() if verbose: print('about to get pid') filename = os.path.join(just_one_dir, string) try: file_ = open(filename, 'r') except (OSError, IOError): dummy, open_extra, dummy = sys.exc_info() if open_extra.errno == errno.ENOENT: pass else: raise else: pid = int(file_.readline()) file_.close() if pid: if verbose: print('got pid %d' % pid) if pid_exists(verbose, pid): sys.stderr.write("%s: %s is locked\n" % (sys.argv[0], string)) sys.exit(1) else: exit_code = start_command(verbose, command, filename) else: exit_code = start_command(verbose, command, filename) sys.exit(exit_code) main()