Monday, February 4, 2013

Allow only one instance of python script.

What if you need to run python script only if it's not already running? Or kill old copy before run new one? One of the way is:

  • Check if special file exists. If it's true, one copy of script is already running. Now kill it or exit from second copy.
  • Create temporary file with PID of script process.
  • Delete pid-file at the end of the script.
Here is the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import tempfile
import ctypes
import os

# Path to file storing PID of running script process. 
# Place it outside of methods in the beggining, or make sure it visible for all methods, which use it.
pid_file = tempfile.gettempdir() + 'tmp_armor_pid.txt'   

# This method checks if file pid_file exists. 
#  If it was found, depends of mode - exit, or kill process which PID is stored in file.  
def scriptStarter(mode = 'force'):
    '''
        if mode  = force - kill runing script and run new one
        if mode != force - run script only if it's not already running
    '''
    if os.path.exists(pid_file):
        print 'old copy found'
        if mode == 'force':
            print 'running copy found, killing it'
            # reading PID from file and convert it to int
            pid = int((open(pid_file).read()))  
            print 'pid have been read:', pid
            # If you use pythton 2.7 or above just use os.kill to terminate PID process.
            # In case of python 2.6 run method killing selected PID
            kill(pid)         

        else:
            print 'running copy found, leaving'
            # not force mode. Just don't run new copy. Leaving.
            raise SystemExit           

 # If we are here, mode == force, old copy killed, writing PID for new script process 
    open(pid_file, 'w').write(str(os.getpid()))  


def kill(pid):
    """kill function for Win32"""
    kernel32 = ctypes.windll.kernel32
    handle = kernel32.OpenProcess(1, 0, pid)
    return (0 != kernel32.TerminateProcess(handle, 0))

# Delete pid-file befor script finish.  
# Dont forget to run this method at the end of the script
# If you use PyQt call it in overloaded closeEvent() 
def removePIDfile():
    print 'deleting pidfile'
    try:
        os.remove(pid_file)
    except OSError:
        pass
    return


def main():
 # check if script is already running 
    scriptStarter('force')    
 '''YOUR SCRIPT CODE HERE'''
 
 # remove pid-file before exit.
 removePIDfile()

if __name__=="__main__":
    main()

Sunday, February 3, 2013

Sublime Text editor customization.

Sublime Text - very powerful and flexible text editor. It has syntax highlight and auto-complete for different programming languages, including python. Also, you can find syntax highlighting files for maya MEL. One of the most useful thing in Sublime is multiline edit. This feature is awesome. Check official web site of this editor for more info and download. I'm sure you will like it.
Although it has nice look by default i want to tell you about two improvements i use to get look of it like on screenshot below: