i would like my Python script to check, if it is already running and if yes, kill the old process. i tried this, but it doesn't really work...
import os
import subprocess
import signal
process_name = "python " + os.path.abspath(__file__)
proc = subprocess.Popen(["pgrep", process_name], stdout=subprocess.PIPE)
# Kill process.
for pid in proc.stdout:
os.kill(int(pid), signal.SIGTERM)
# Check if the process that we killed is alive.
try:
os.kill(int(pid), 0)
raise Exception("""wasn't able to kill the process
HINT:use signal.SIGKILL or signal.SIGABORT""")
except OSError as ex:
continue
It doesn't kill the old process and runs multiple times now.
Determining if a python script is running using your pgrep
based method is not reliable. For example:
> ps -ef | grep 'python sleep.py'
userid 21107 2069 0 12:51 pts/3 00:00:00 python sleep.py
userid 21292 2069 0 13:08 pts/3 00:00:00 grep python sleep.py
> pgrep 'python sleep.py'
>
Additional difficulties in identifying a running python script by its name:
python
string may differ, depending on how the script is executed, for example it may look like this:/usr/bin/python2.7 sleep.py
os.path.abspath(__file__)
method to locate the script in the process name may fail if the script is a symlink to the actual file and can be executed from both locationsExample:
> cat abs_path.py
import os
print os.path.abspath(__file__)
> ls -l abs_path.py
lrwxrwxrwx 1 userid at 15 Apr 22 13:22 abs_path.py -> bin/abs_path.py
> python abs_path.py
/home/userid/abs_path.py
> python bin/abs_path.py
/home/userid/bin/abs_path.py
My personal preference in approaching such problem is to have the script create a pidfile in a unique, well known location in which it'll place its own pid. This makes determining the pid of a potentially already running process much more reliable.
You'll still have to take into account the race condition in creating the pidfile and reliably writing into it self's pid. Typically re-checking the file content and committing suicide if mismatches are detected is sufficient to ensure at most a single running process instance exists, regardless of how the process is actually named.