39

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?

jww
  • 97,681
  • 90
  • 411
  • 885
Andreas Thomas
  • 4,360
  • 3
  • 23
  • 15

9 Answers9

56

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
Aaron Maenpaa
  • 119,832
  • 11
  • 95
  • 108
29

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.

Mark Harrison
  • 297,451
  • 125
  • 333
  • 465
13

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"
dF.
  • 74,139
  • 30
  • 130
  • 136
10

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')
felbus
  • 2,639
  • 2
  • 24
  • 30
9

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.

sivabudh
  • 31,807
  • 63
  • 162
  • 228
  • 1
    This will fail so much when the process have multiple childs. – Phyo Arkar Lwin May 01 '11 at 13:38
  • This solution will give wrong results if one tries to search a process only by name, without full path 'path/of/process', because "ps -eaf | grep" will also include the grep process itself, thus always providing non-empty output. – John Smith Aug 17 '21 at 15:43
6

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).

jww
  • 97,681
  • 90
  • 411
  • 885
Marius
  • 3,589
  • 3
  • 27
  • 30
5

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.

timblaktu
  • 375
  • 3
  • 11
  • 2
    If you are running some versions of Linux, the number of unique PIDs is 32768 or whatever is in /proc/sys/kernel/pid_max which makes a reused PID unlikely for short running programs. – Vicky T Jan 06 '12 at 19:57
4

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.

mr.m
  • 41
  • 1
0

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
Maksym Kozlenko
  • 10,273
  • 2
  • 66
  • 55