Checking Running Python Script Within the Python Script

Check to see if python script is running

Drop a pidfile somewhere (e.g. /tmp). Then you can check to see if the process is running by checking to see if the PID in the file exists. Don't forget to delete the file when you shut down cleanly, and check for it when you start up.

#/usr/bin/env python

import os
import sys

pid = str(os.getpid())
pidfile = "/tmp/mydaemon.pid"

if os.path.isfile(pidfile):
print "%s already exists, exiting" % pidfile
sys.exit()
file(pidfile, 'w').write(pid)
try:
# Do some actual work here
finally:
os.unlink(pidfile)

Then you can check to see if the process is running by checking to see if the contents of /tmp/mydaemon.pid are an existing process. Monit (mentioned above) can do this for you, or you can write a simple shell script to check it for you using the return code from ps.

ps up `cat /tmp/mydaemon.pid ` >/dev/null && echo "Running" || echo "Not running"

For extra credit, you can use the atexit module to ensure that your program cleans up its pidfile under any circumstances (when killed, exceptions raised, etc.).

Check a Python Script Is Running

Not sure about what you are asking but as given this may help, so if you just want to call one python script from another then you can use script 1

 #!/usr/bin/python 
from subprocess import call
call(["python", "update.py"])

Save this file in a script named script1 and run it, it will compile update.py.
If you want to check for any syntax error in update.py then you can use script 2

#!/usr/bin/python
from subprocess import call
call(["python","-m","py_compile", "update.py"])

If script2 compiles without any error then it shows that there is no syntax error in your program.

Thirdly if you want to check if update.py is running currently or not you can use script 3

#!/usr/bin/python
import psutil
import sys
from subprocess import Popen

for process in psutil.process_iter():
if process.cmdline() == ['python', 'update.py']:
sys.exit('Process found: exiting.')

print('Process not found: starting it.')
Popen(['python', 'update.py'])

This last script will tell if your script is running or not and if it is not running it will compile it.

Checking running python script within the python script

You can try using the lockfile-create command with the r flag to retry a specified amount of times catching a CalledProcessError and exiting, the -p flag will store the pid of the process :

import os
import sys
from time import sleep

from subprocess import check_call, CalledProcessError

try:
check_call(["lockfile-create", "-q","-p", "-r", "0", "-l", "my.lock"])
except CalledProcessError as e:
print("{} is already running".format(sys.argv[0]))
print(e.returncode)
exit(1)

# main body

for i in range(10):
sleep(2)
print(1)

check_call(["rm","-f","my.lock"])

Running a test.py script with the code above while one is already running outputs the following:

$ python  lock.py 
lock.py is already running
4

Options

-q, --quiet

Suppress any output. Success or failure will only be indicated by the exit status.

-v, --verbose

Enable diagnostic output.

-l, --lock-name

Do not append .lock to the filename. This option applies to lockfile-create, lockfile-remove, lockfile-touch, or lockfile-check.

-p, --use-pid

Write the current process id (PID) to the lockfile whenever a lockfile is created, and use that pid when checking a lock's validity. See the lockfile_create(3) manpage for more information. This option applies to lockfile-create, lockfile-remove, lockfile-touch, and lockfile-check.

-o, --oneshot

Touch the lock and exit immediately. This option applies to lockfile-touch and mail-touchlock. When not provided, these commands will run forever, touching the lock once every minute until killed.

-r retry-count, --retry retry-count

Try to lock filename retry-count times before giving up. Each attempt will be delayed a bit longer than the last (in 5 second increments) until reaching a maximum delay of one minute between retries. If retry-count is unspecified, the default is 9 which will give up after 180 seconds (3 minutes) if all 9 lock attempts fail.

Description

The lockfile_create function creates a lockfile in an NFS safe way.

If flags is set to L_PID then lockfile_create will not only check for an existing lockfile, but it will read the contents as well to see if it contains a process id in ASCII. If so, the lockfile is only valid if that process still exists.

If the lockfile is on a shared filesystem, it might have been created by a process on a remote host. Thus the process-id checking is useless and the L_PID flag should not be set. In this case, there is no good way to see if a lockfile is stale. Therefore if the lockfile is older then 5 minutes, it will be removed. That is why the lockfile_touch function is provided: while holding the lock, it needs to be refreshed regularly (every minute or so) by calling lockfile_touch ().

The lockfile_check function checks if a valid lockfile is already present without trying to create a new lockfile.

Finally the lockfile_remove function removes the lockfile.

The Algorithm

The algorithm that is used to create a lockfile in an atomic way, even over NFS, is as follows:

1

A unique file is created. In printf format, the name of the file is .lk%05d%x%s. The first argument (%05d) is the current process id. The second argument (%x) consists of the 4 minor bits of the value returned by time(2). The last argument is the system hostname.

2

Then the lockfile is created using link(2). The return value of link is ignored.

3

Now the lockfile is stat()ed. If the stat fails, we go to step 6.

4

The stat value of the lockfile is compared with that of the temporary file. If they are the same, we have the lock. The temporary file is deleted and a value of 0 (success) is returned to the caller.

5

A check is made to see if the existing lockfile is a valid one. If it isn't valid, the stale lockfile is deleted.

6

Before retrying, we sleep for n seconds. n is initially 5 seconds, but after every retry 5 extra seconds is added up to a maximum of 60 seconds (an incremental backoff). Then we go to step 2 up to retries times.

There seems to be an equivalent package called lockfile-progs on redhat.

On mac you could use lockfile and do something like:

import os
import sys
from time import sleep
import os
from subprocess import Popen, CalledProcessError, check_call

p = Popen(["lockfile", "-r", "0", "my.lock"])
p.wait()
if p.returncode == 0:
with open("my.pid", "w") as f:
f.write(str(os.getpid()))
else:
try:
with open("my.pid") as f:
# see if process is still running or lockfile
# is left over from previous run.
r = f.read()
check_call(["kill", "-0", "{}".format(r)])
except CalledProcessError:
# remove old lock file and create new
check_call(["rm", "-f", "my.lock"])
check_call(["lockfile", "-r", "0", "my.lock"])
# update pid
with open("my.pid", "w") as out:
out.write(str(os.getpid()))
print("Deleted stale lockfile.")
else:
print("{} is already running".format(sys.argv[0]))
print(p.returncode)
exit(1)
# main body

for i in range(10):
sleep(1)
print(1)
check_call(["rm", "-f", "my.lock"])

In your case maybe using a socket would work:

from socket import socket, gethostname, error, SO_REUSEADDR, SOL_SOCKET
from sys import argv
import errno

sock = socket()

# Create a socket object
host = gethostname()
# /proc/sys/net/ipv4/ip_local_port_range is 32768 61000 on my Ubuntu Machine
port = 60001
# allow connection in TIME_WAIT
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

try:
sock.bind((host, port))
sock.connect((host, port))
except error as e:
# [Errno 99] Cannot assign requested address
if e.errno == errno.EADDRNOTAVAIL:
print("{} is already running".format(argv[0]))
exit(1)
# else raise the error
else:
raise e

# main body
from time import sleep

while True:
print(1)
sleep(2)

sock.close()

Running a Python script within shell script - Check status

First, you can pass the desired exit code as an argument to sys.exit in your python script.

Second, the exit code of the most recently exited process can be found in the bash parameter $?. However, you may not need to check it explicitly:

if python script.py; then
echo "Exit code of 0, success"
else
echo "Exit code of $?, failure"
fi

To check the exit code explicitly, you need to supply a conditional expression to the if statement:

python script.py
if [[ $? = 0 ]]; then
echo "success"
else
echo "failure: $?"
fi

How to determine if Python script was run via command line?

I don't think there's any reliable way to detect this (especially in a cross-platform manner). For example on OS X, when you double-click a .py file and it tuns with "Python Launcher", it runs in a terminal, identically to if you execute it manually.

Although it may have other issues, you could package the script up with something like py2exe or Platypus, then you can have the double-clickable icon run a specific bit of code to differentiate (import mycode; mycode.main(gui = True) for example)

How to display list of running processes Python?

Try this command:

ps -ef | grep python

ps stands for process status



Related Topics



Leave a reply



Submit