Scan memory of external process in windows with Python 3 - python

I've been trying doing this for days without any success, so I hope that someone can help me.
My goal is to scan the memory of a process once I have the pid, and actually read the strings of that process.
For example I want to do something like this.
Let's say that I have a notepad open and the pid is = 4578.
I want first to check if in the process memory there is the string "cold water", if the string is in the memory then I would do a deeper scan extracting all the strings in the memory, otherwise I wouldnt.
from ctypes import *
import ctypes
import psutil
import time
def get_client_pid(process_name):
pid = None
for proc in psutil.process_iter():
if proc.name() == process_name:
pid = int(proc.pid)
print("Found, PID = ", pid)
break
return pid
pid = get_client_pid("notepad.exe.exe")
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010
process = windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,False,pid)
readprocess = windll.kernel32.ReadProcessMemory
rdbuf = ctypes.c_uint()
bytread = ctypes.c_size_t()
base = 0x00400000
for addr in range(base, base + 11):
try:
if readprocess(process, ctypes.c_void_p(addr), ctypes.byref(rdbuf), ctypes.sizeof(rdbuf),ctypes.byref(bytread)):
print(rdbuf.value)
except Exception as e:
print("ERROR", e)
This is an example code I found somewhere and edited a bit.
How can I know all the addresses in memory that belong to a specific process?
is a better or simpler module than ctypes to do this?
thanks for help

it seems that you have some typing errors. Try replacing this code:
pid = get_client_pid("notepad.exe.exe")
With this one:
pid = get_client_pid("notepad.exe")

Related

reading data from process' memory with Python

I'm trying to read data from memory of a process by inputing the process name, then finding PID using psutil. So far I have this:
import ctypes
from ctypes import *
from ctypes.wintypes import *
import win32ui
import psutil # install, not a default module
import sys
# input process name
nameprocess = "notepad.exe"
# find pid
def getpid():
for proc in psutil.process_iter():
if proc.name() == nameprocess:
return proc.pid
PROCESS_ID = getpid()
if PROCESS_ID == None:
print "Process was not found"
sys.exit(1)
# read from addresses
STRLEN = 255
PROCESS_VM_READ = 0x0010
process = windll.kernel32.OpenProcess(PROCESS_VM_READ, 0, PROCESS_ID)
readProcMem = windll.kernel32.ReadProcessMemory
buf = ctypes.create_string_buffer(STRLEN)
for i in range(1,100):
if readProcMem(process, hex(i), buf, STRLEN, 0):
print buf.raw
The last for loop should read and print contents of the first 100 addresses in the process if I'm getting this right. Only thing is, the output looks like complete gibberish.
There are 2 problems for me here: first, am I really reading the addresses from the selected process this way? And second, how can I figure how long in the loop I should go, if there is maybe some kind of end address?
I didn't install psutil, but just pulled a process ID and valid virtual address using Task Manager and SysInternals VMMap. The numbers will vary of course.
Good practice with ctypes is to define the argument types and return value via .argtypes and .restype. Get your own instance of the kernel32 library because changing the attributes of the cached windll.kernel32 instance could cause issues with other modules using ctypes and kernel32.
You need a valid virtual address. In answer to your 2nd problem, I think VMMap proves there is a way to do it. Pick up a copy of Windows Internals to learn the techniques.
from ctypes import *
from ctypes.wintypes import *
PROCESS_ID = 9476 # From TaskManager for Notepad.exe
PROCESS_HEADER_ADDR = 0x7ff7b81e0000 # From SysInternals VMMap utility
# read from addresses
STRLEN = 255
PROCESS_VM_READ = 0x0010
k32 = WinDLL('kernel32')
k32.OpenProcess.argtypes = DWORD,BOOL,DWORD
k32.OpenProcess.restype = HANDLE
k32.ReadProcessMemory.argtypes = HANDLE,LPVOID,LPVOID,c_size_t,POINTER(c_size_t)
k32.ReadProcessMemory.restype = BOOL
process = k32.OpenProcess(PROCESS_VM_READ, 0, PROCESS_ID)
buf = create_string_buffer(STRLEN)
s = c_size_t()
if k32.ReadProcessMemory(process, PROCESS_HEADER_ADDR, buf, STRLEN, byref(s)):
print(s.value,buf.raw)
Output (Note 'MZ' is the start of a program header):
255 b'MZ\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x0e\x1f\xba\x0e\x00\xb4\t\xcd!\xb8\x01L\xcd!This program cannot be run in DOS mode.\r\r\n$\x00\x00\x00\x00\x00\x00\x00\xd0\x92\xa7\xd1\x94\xf3\xc9\x82\x94\xf3\xc9\x82\x94\xf3\xc9\x82\x9d\x8bZ\x82\x8a\xf3\xc9\x82\xfb\x97\xca\x83\x97\xf3\xc9\x82\xfb\x97\xcd\x83\x83\xf3\xc9\x82\xfb\x97\xcc\x83\x91\xf3\xc9\x82\xfb\x97\xc8\x83\x8f\xf3\xc9\x82\x94\xf3\xc8\x82\x82\xf2\xc9\x82\xfb\x97\xc1\x83\x8d\xf3\xc9\x82\xfb\x976\x82\x95\xf3\xc9\x82\xfb\x97\xcb\x83\x95\xf3\xc9\x82Rich\x94\xf3\xc9\x82\x00\x00\x00\x00\x00\x00\x00\x00PE\x00\x00d\x86\x06\x00^\'\x0f\x84\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00"'
Here's a screenshot of VMMap indicating the header address of notepad.exe:
Here's a screenshot of a hexdump of the content of notepad.exe that matches the output of the program:
On Windows, the PyMem library can help you with that: https://pymem.readthedocs.io/

How to terminate process from Python using pid?

I'm trying to write some short script in python which would start another python code in subprocess if is not already started else terminate terminal & app (Linux).
So it looks like:
#!/usr/bin/python
from subprocess import Popen
text_file = open(".proc", "rb")
dat = text_file.read()
text_file.close()
def do(dat):
text_file = open(".proc", "w")
p = None
if dat == "x" :
p = Popen('python StripCore.py', shell=True)
text_file.write( str( p.pid ) )
else :
text_file.write( "x" )
p = # Assign process by pid / pid from int( dat )
p.terminate()
text_file.close()
do( dat )
Have problem of lacking knowledge to name proces by pid which app reads from file ".proc".
The other problem is that interpreter says that string named dat is not equal to "x" ??? What I've missed ?
Using the awesome psutil library it's pretty simple:
p = psutil.Process(pid)
p.terminate() #or p.kill()
If you don't want to install a new library, you can use the os module:
import os
import signal
os.kill(pid, signal.SIGTERM) #or signal.SIGKILL
See also the os.kill documentation.
If you are interested in starting the command python StripCore.py if it is not running, and killing it otherwise, you can use psutil to do this reliably.
Something like:
import psutil
from subprocess import Popen
for process in psutil.process_iter():
if process.cmdline() == ['python', 'StripCore.py']:
print('Process found. Terminating it.')
process.terminate()
break
else:
print('Process not found: starting it.')
Popen(['python', 'StripCore.py'])
Sample run:
$python test_strip.py #test_strip.py contains the code above
Process not found: starting it.
$python test_strip.py
Process found. Terminating it.
$python test_strip.py
Process not found: starting it.
$killall python
$python test_strip.py
Process not found: starting it.
$python test_strip.py
Process found. Terminating it.
$python test_strip.py
Process not found: starting it.
Note: In previous psutil versions cmdline was an attribute instead of a method.
I wanted to do the same thing as, but I wanted to do it in the one file.
So the logic would be:
if a script with my name is running, kill it, then exit
if a script with my name is not running, do stuff
I modified the answer by Bakuriu and came up with this:
from os import getpid
from sys import argv, exit
import psutil ## pip install psutil
myname = argv[0]
mypid = getpid()
for process in psutil.process_iter():
if process.pid != mypid:
for path in process.cmdline():
if myname in path:
print "process found"
process.terminate()
exit()
## your program starts here...
Running the script will do whatever the script does. Running another instance of the script will kill any existing instance of the script.
I use this to display a little PyGTK calendar widget which runs when I click the clock. If I click and the calendar is not up, the calendar displays. If the calendar is running and I click the clock, the calendar disappears.
So, not directly related but this is the first question that appears when you try to find how to terminate a process running from a specific folder using Python.
It also answers the question in a way(even though it is an old one with lots of answers).
While creating a faster way to scrape some government sites for data I had an issue where if any of the processes in the pool got stuck they would be skipped but still take up memory from my computer. This is the solution I reached for killing them, if anyone knows a better way to do it please let me know!
import pandas as pd
import wmi
from re import escape
import os
def kill_process(kill_path, execs):
f = wmi.WMI()
esc = escape(kill_path)
temp = {'id':[], 'path':[], 'name':[]}
for process in f.Win32_Process():
temp['id'].append(process.ProcessId)
temp['path'].append(process.ExecutablePath)
temp['name'].append(process.Name)
temp = pd.DataFrame(temp)
temp = temp.dropna(subset=['path']).reset_index().drop(columns=['index'])
temp = temp.loc[temp['path'].str.contains(esc)].loc[temp.name.isin(execs)].reset_index().drop(columns=['index'])
[os.system('taskkill /PID {} /f'.format(t)) for t in temp['id']]

Ensuring only one process is executed for a long running process using python

I am looking for best practice for ensuring a script executed by a cron job every minute only has one running instance. For e.g. if I have a cron that executed every minute and in case the process takes longer then one minute then do not execute another till done.
For now I have the below function. In essence I get the name of the current process and I do a ps grep to see if the count of the current process is listed. Kinda messy so I was looking for a more pythonic way.
I place the code on top of a file. It does work but again messy.
def doRunCount(stop=False,min_run=1):
import inspect
current_file = inspect.getfile( inspect.currentframe() )
print current_file
fn = current_file.split()
run_check = os.popen('ps aux | grep python').read().strip().split('\n')
run_count = 0
for i in run_check:
if i.find('/bin/sh')<0:
if i.find(current_file)>=0:
run_count = run_count + 1
if run_count>min_run:
print 'max proccess already running'
exit()
return run_count
I don't know if you could describe this as best practice, but I would use a pid file. Here's a snippet similar to what I have used several times to ensure only one instance of a specific app is running.
import os, sys
PID_FILE = '/path/to/somewhere.pid'
if os.path.exists( PID_FILE ):
pid = int(open( PID_FILE,'rb').read().rstrip('\n'))
if len(os.popen('ps %i' % pid).read().split('\n')) > 2:
print "Already Running as pid: %i" % pid
sys.exit(1)
# If we get here, we know that the app is not running so we can start a new one...
pf = open(PID_FILE,'wb')
pf.write('%i\n' % os.getpid())
pf.close()
if __name__ == '__main__':
#Do something here!
pass
Like I said this is similar to what I have used, but I just re-wrote this snippet to be a little more elegant. But it should get the general concept across! Hope this helps.
Here is a slight modification which should clear up any issues arising from a process crash.
This code will not only validate that a pid file exists, but that the pid in the file is still alive and that the pid is still the same executable.
import os, sys
PID_FILE = '/path/to/somewhere.pid'
if os.path.exists( PID_FILE ):
pid = int(open( PID_FILE,'rb').read().rstrip('\n'))
pinfo = os.popen('ps %i' % pid).read().split('\n')
if len( pinfo ) > 2:
# You might need to modify this to your own usage...
if pinfo[1].count( sys.argv[0] ):
# Varify that the process found by 'ps' really is still running...
print "Already Running as pid: %i" % pid
sys.exit(1)
# If we get here, we know that the app is not running so we can start a new one...
pf = open(PID_FILE,'wb')
pf.write('%i\n' % os.getpid())
pf.close()
if __name__ == '__main__':
#Do something here!
pass
After that I just leave the pid file, since you don't really need to worry about a false positive. Note you might need to modify the second step of validation to your own specific usage!

Check to see if python script is running

I have a python daemon running as a part of my web app/ How can I quickly check (using python) if my daemon is running and, if not, launch it?
I want to do it that way to fix any crashes of the daemon, and so the script does not have to be run manually, it will automatically run as soon as it is called and then stay running.
How can i check (using python) if my script is running?
A technique that is handy on a Linux system is using domain sockets:
import socket
import sys
import time
def get_lock(process_name):
# Without holding a reference to our socket somewhere it gets garbage
# collected when the function exits
get_lock._lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
try:
# The null byte (\0) means the socket is created
# in the abstract namespace instead of being created
# on the file system itself.
# Works only in Linux
get_lock._lock_socket.bind('\0' + process_name)
print 'I got the lock'
except socket.error:
print 'lock exists'
sys.exit()
get_lock('running_test')
while True:
time.sleep(3)
It is atomic and avoids the problem of having lock files lying around if your process gets sent a SIGKILL
You can read in the documentation for socket.close that sockets are automatically closed when garbage collected.
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.).
The pid library can do exactly this.
from pid import PidFile
with PidFile():
do_something()
It will also automatically handle the case where the pidfile exists but the process is not running.
My solution is to check for the process and command line arguments
Tested on windows and ubuntu linux
import psutil
import os
def is_running(script):
for q in psutil.process_iter():
if q.name().startswith('python'):
if len(q.cmdline())>1 and script in q.cmdline()[1] and q.pid !=os.getpid():
print("'{}' Process is already running".format(script))
return True
return False
if not is_running("test.py"):
n = input("What is Your Name? ")
print ("Hello " + n)
Of course the example from Dan will not work as it should be.
Indeed, if the script crash, rise an exception, or does not clean pid file, the script will be run multiple times.
I suggest the following based from another website:
This is to check if there is already a lock file existing
\#/usr/bin/env python
import os
import sys
if os.access(os.path.expanduser("~/.lockfile.vestibular.lock"), os.F_OK):
#if the lockfile is already there then check the PID number
#in the lock file
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "r")
pidfile.seek(0)
old_pid = pidfile.readline()
# Now we check the PID from lock file matches to the current
# process PID
if os.path.exists("/proc/%s" % old_pid):
print "You already have an instance of the program running"
print "It is running as process %s," % old_pid
sys.exit(1)
else:
print "File is there but the program is not running"
print "Removing lock file for the: %s as it can be there because of the program last time it was run" % old_pid
os.remove(os.path.expanduser("~/.lockfile.vestibular.lock"))
This is part of code where we put a PID file in the lock file
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()
This code will check the value of pid compared to existing running process., avoiding double execution.
I hope it will help.
There are very good packages for restarting processes on UNIX. One that has a great tutorial about building and configuring it is monit. With some tweaking you can have a rock solid proven technology keeping up your daemon.
Came across this old question looking for solution myself.
Use psutil:
import psutil
import sys
from subprocess import Popen
for process in psutil.process_iter():
if process.cmdline() == ['python', 'your_script.py']:
sys.exit('Process found: exiting.')
print('Process not found: starting it.')
Popen(['python', 'your_script.py'])
There are a myriad of options. One method is using system calls or python libraries that perform such calls for you. The other is simply to spawn out a process like:
ps ax | grep processName
and parse the output. Many people choose this approach, it isn't necessarily a bad approach in my view.
I'm a big fan of Supervisor for managing daemons. It's written in Python, so there are plenty of examples of how to interact with or extend it from Python. For your purposes the XML-RPC process control API should work nicely.
Try this other version
def checkPidRunning(pid):
'''Check For the existence of a unix pid.
'''
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
# Entry point
if __name__ == '__main__':
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp", __program__+".pid")
if os.path.isfile(pidfile) and checkPidRunning(int(file(pidfile,'r').readlines()[0])):
print "%s already exists, exiting" % pidfile
sys.exit()
else:
file(pidfile, 'w').write(pid)
# Do some actual work here
main()
os.unlink(pidfile)
Rather than developing your own PID file solution (which has more subtleties and corner cases than you might think), have a look at supervisord -- this is a process control system that makes it easy to wrap job control and daemon behaviors around an existing Python script.
The other answers are great for things like cron jobs, but if you're running a daemon you should monitor it with something like daemontools.
ps ax | grep processName
if yor debug script in pycharm always exit
pydevd.py --multiproc --client 127.0.0.1 --port 33882 --file processName
try this:
#/usr/bin/env python
import os, sys, atexit
try:
# Set PID file
def set_pid_file():
pid = str(os.getpid())
f = open('myCode.pid', 'w')
f.write(pid)
f.close()
def goodby():
pid = str('myCode.pid')
os.remove(pid)
atexit.register(goodby)
set_pid_file()
# Place your code here
except KeyboardInterrupt:
sys.exit(0)
Here is more useful code (with checking if exactly python executes the script):
#! /usr/bin/env python
import os
from sys import exit
def checkPidRunning(pid):
global script_name
if pid<1:
print "Incorrect pid number!"
exit()
try:
os.kill(pid, 0)
except OSError:
print "Abnormal termination of previous process."
return False
else:
ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
process_exist = os.system(ps_command)
if process_exist == 0:
return True
else:
print "Process with pid %s is not a Python process. Continue..." % pid
return False
if __name__ == '__main__':
script_name = os.path.basename(__file__)
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp/", script_name+".pid")
if os.path.isfile(pidfile):
print "Warning! Pid file %s existing. Checking for process..." % pidfile
r_pid = int(file(pidfile,'r').readlines()[0])
if checkPidRunning(r_pid):
print "Python process with pid = %s is already running. Exit!" % r_pid
exit()
else:
file(pidfile, 'w').write(pid)
else:
file(pidfile, 'w').write(pid)
# main programm
....
....
os.unlink(pidfile)
Here is string:
ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
returns 0 if "grep" is successful, and the process "python" is currently running with the name of your script as a parameter .
A simple example if you only are looking for a process name exist or not:
import os
def pname_exists(inp):
os.system('ps -ef > /tmp/psef')
lines=open('/tmp/psef', 'r').read().split('\n')
res=[i for i in lines if inp in i]
return True if res else False
Result:
In [21]: pname_exists('syslog')
Out[21]: True
In [22]: pname_exists('syslog_')
Out[22]: False
I was looking for an answer on this and in my case, came to mind a very easy and very good solution, in my opinion (since it's not possible to exist a false positive on this, I guess - how can the timestamp on the TXT be updated if the program doesn't do it):
--> just keep writing on a TXT the current timestamp in some time interval, depending on your needs (here each half hour was perfect).
If the timestamp on the TXT is outdated relatively to the current one when you check, then there was a problem on the program and it should be restarted or what you prefer to do.
A portable solution that relies on multiprocessing.shared_memory:
import atexit
from multiprocessing import shared_memory
_ensure_single_process_store = {}
def ensure_single_process(name: str):
if name in _ensure_single_process_store:
return
try:
shm = shared_memory.SharedMemory(name='ensure_single_process__' + name,
create=True,
size=1)
except FileExistsError:
print(f"{name} is already running!")
raise
_ensure_single_process_store[name] = shm
atexit.register(shm.unlink)
Usually you wouldn't have to use atexit, but sometimes it helps to clean up upon abnormal exit.
Consider the following example to solve your problem:
#!/usr/bin/python
# -*- coding: latin-1 -*-
import os, sys, time, signal
def termination_handler (signum,frame):
global running
global pidfile
print 'You have requested to terminate the application...'
sys.stdout.flush()
running = 0
os.unlink(pidfile)
running = 1
signal.signal(signal.SIGINT,termination_handler)
pid = str(os.getpid())
pidfile = '/tmp/'+os.path.basename(__file__).split('.')[0]+'.pid'
if os.path.isfile(pidfile):
print "%s already exists, exiting" % pidfile
sys.exit()
else:
file(pidfile, 'w').write(pid)
# Do some actual work here
while running:
time.sleep(10)
I suggest this script because it can be executed one time only.
Using bash to look for a process with the current script's name. No extra file.
import commands
import os
import time
import sys
def stop_if_already_running():
script_name = os.path.basename(__file__)
l = commands.getstatusoutput("ps aux | grep -e '%s' | grep -v grep | awk '{print $2}'| awk '{print $2}'" % script_name)
if l[1]:
sys.exit(0);
To test, add
stop_if_already_running()
print "running normally"
while True:
time.sleep(3)
This is what I use in Linux to avoid starting a script if already running:
import os
import sys
script_name = os.path.basename(__file__)
pidfile = os.path.join("/tmp", os.path.splitext(script_name)[0]) + ".pid"
def create_pidfile():
if os.path.exists(pidfile):
with open(pidfile, "r") as _file:
last_pid = int(_file.read())
# Checking if process is still running
last_process_cmdline = "/proc/%d/cmdline" % last_pid
if os.path.exists(last_process_cmdline):
with open(last_process_cmdline, "r") as _file:
cmdline = _file.read()
if script_name in cmdline:
raise Exception("Script already running...")
with open(pidfile, "w") as _file:
pid = str(os.getpid())
_file.write(pid)
def main():
"""Your application logic goes here"""
if __name__ == "__main__":
create_pidfile()
main()
This approach works good without any dependency on an external module.

How to check if a process is still running using Python on Linux? [duplicate]

This question already has answers here:
How to check if there exists a process with a given pid in Python?
(15 answers)
Closed 9 years ago.
The only nice way I've found is:
import sys
import os
try:
os.kill(int(sys.argv[1]), 0)
print "Running"
except:
print "Not running"
(Source)
But is this reliable? Does it work with every process and every distribution?
Mark's answer is the way to go, after all, that's why the /proc file system is there. For something a little more copy/pasteable:
>>> import os.path
>>> os.path.exists("/proc/0")
False
>>> os.path.exists("/proc/12")
True
on linux, you can look in the directory /proc/$PID to get information about that process. In fact, if the directory exists, the process is running.
It should work on any POSIX system (although looking at the /proc filesystem, as others have suggested, is easier if you know it's going to be there).
However: os.kill may also fail if you don't have permission to signal the process. You would need to do something like:
import sys
import os
import errno
try:
os.kill(int(sys.argv[1]), 0)
except OSError, err:
if err.errno == errno.ESRCH:
print "Not running"
elif err.errno == errno.EPERM:
print "No permission to signal this process!"
else:
print "Unknown error"
else:
print "Running"
I use this to get the processes, and the count of the process of the specified name
import os
processname = 'somprocessname'
tmp = os.popen("ps -Af").read()
proccount = tmp.count(processname)
if proccount > 0:
print(proccount, ' processes running of ', processname, 'type')
Here's the solution that solved it for me:
import os
import subprocess
import re
def findThisProcess( process_name ):
ps = subprocess.Popen("ps -eaf | grep "+process_name, shell=True, stdout=subprocess.PIPE)
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
return output
# This is the function you can use
def isThisRunning( process_name ):
output = findThisProcess( process_name )
if re.search('path/of/process'+process_name, output) is None:
return False
else:
return True
# Example of how to use
if isThisRunning('some_process') == False:
print("Not running")
else:
print("Running!")
I'm a Python + Linux newbie, so this might not be optimal. It solved my problem, and hopefully will help other people as well.
But is this reliable? Does it work with every process and every distribution?
Yes, it should work on any Linux distribution. Be aware that /proc is not easily available on Unix based systems, though (FreeBSD, OSX).
Seems to me a PID-based solution is too vulnerable. If the process you're trying to check the status of has been terminated, its PID can be reused by a new process. So, IMO ShaChris23 the Python + Linux newbie gave the best solution to the problem. Even it only works if the process in question is uniquely identifiable by its command string, or you are sure there would be only one running at a time.
i had problems with the versions above (for example the function found also part of the string and such things...)
so i wrote my own, modified version of Maksym Kozlenko's:
#proc -> name/id of the process
#id = 1 -> search for pid
#id = 0 -> search for name (default)
def process_exists(proc, id = 0):
ps = subprocess.Popen("ps -A", shell=True, stdout=subprocess.PIPE)
ps_pid = ps.pid
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
for line in output.split("\n"):
if line != "" and line != None:
fields = line.split()
pid = fields[0]
pname = fields[3]
if(id == 0):
if(pname == proc):
return True
else:
if(pid == proc):
return True
return False
I think it's more reliable, easier to read and you have the option to check for process ids or names.
Sligtly modified version of ShaChris23 script. Checks if proc_name value is found within process args string (for example Python script executed with python ):
def process_exists(proc_name):
ps = subprocess.Popen("ps ax -o pid= -o args= ", shell=True, stdout=subprocess.PIPE)
ps_pid = ps.pid
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
for line in output.split("\n"):
res = re.findall("(\d+) (.*)", line)
if res:
pid = int(res[0][0])
if proc_name in res[0][1] and pid != os.getpid() and pid != ps_pid:
return True
return False

Categories

Resources