8

I have a python script that I want to only allow to be running once on a machine. I want it to print something like "Error, already running" if it is already running, whether its running in the background or in a different ssh session. How would I do this? Here is my script.

import urllib, urllib2, sys
num = sys.argv[1]
print 'Calling'
phones = [
'http://phone1/index.htm',
'http://phone2/index.htm',
'https://phone3/index.htm',
'https://phone4/index.htm',
'https://phone5/index.htm'
]
data = urllib.urlencode({"NUMBER":num, "DIAL":"Dial", "active_line":1})
while 1: 
    for phone in phones:
        try:
            urllib2.urlopen(phone,data) # make call
            urllib2.urlopen(phone+"?dialeddel=0") # clear logs
        except: pass

P.S I am using CentOS 5 if that matters.

Asclepius
  • 57,944
  • 17
  • 167
  • 143
CJ Sculti
  • 759
  • 3
  • 12
  • 21

3 Answers3

3
  1. You can implement a lock on the file.
  2. Create a temp file at the start of the execution and check if that file is present before running the script.

Refer to this post for answer- Check to see if python script is running

Community
  • 1
  • 1
fatrock92
  • 827
  • 1
  • 8
  • 16
3

You can install the single package with pip install single that will use an advisory lock to ensure that only a single instance of a command will run without leaving stale lock files behind.

You can invoke it on your script like this:

single.py -c long-running-script arg1 arg2
aculich
  • 14,545
  • 9
  • 64
  • 71
  • PIP command not found. How would I do this on centos? There is no package single with yum – CJ Sculti Sep 03 '12 at 16:48
  • You may have to do `sudo easy_install pip` first. Then pip will download the single package automatically from here: http://pypi.python.org/pypi/single/ – aculich Sep 04 '12 at 01:11
  • After installing pip, then doing pip install single, I get this http://pastebin.com/6MTmHkMT – CJ Sculti Sep 04 '12 at 13:32
  • You're using a very old version of python (2.4) that does not have `walk_packages()`. You need to upgrade to at least 2.5, but preferably 2.7 if possible. – aculich Sep 04 '12 at 16:38
0

You could lock an existing file using e.g. flock at start of your script. Then, if the same script is run twice, the latest started would block. See also this question.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • The thing about that is, the script is an infinite loop, so it would never get to the end of the script where the lock is removed. – CJ Sculti Sep 02 '12 at 12:32
  • You could add a handler for `SIGTERM` or `SIGQUIT` which clears a fleg used as a looping condition. – Basile Starynkevitch Sep 02 '12 at 12:44
  • Could you explain to me how to do this and what it means? As I am new to python – CJ Sculti Sep 02 '12 at 13:32
  • You can use the [single wrapper script](http://stackoverflow.com/a/12240440/462302) to avoid leaving stale lock files around. – aculich Sep 02 '12 at 23:03
  • @CJSculti In Linux(and unix) in general there is a thing called a signal. When you run kill program it sends a SIGTERM(signal terminate ), when you press Ctrl-C to stop a program running in a shell it sends SIGINT(signal interrupt). Your program can register a callback with the OS to handle those signals. Then when you send a signal to your program it could clean up nicely and exit. – stonemetal Sep 02 '12 at 23:16