How do you get the process ID of a program in Unix or Linux using Python?

Question:

I’m writing some monitoring scripts in Python and I’m trying to find the cleanest way to get the process ID of any random running program given the name of that program

something like

ps -ef | grep MyProgram

I could parse the output of that however I thought there might be a better way in python

Asked By: James

||

Answers:

Answered By: Derek Swingley

If you are not limiting yourself to the standard library, I like psutil for this.

For instance to find all “python” processes:

>>> import psutil
>>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']]
[{'name': 'python3', 'pid': 21947},
 {'name': 'python', 'pid': 23835}]
Answered By: Mark

Try pgrep. Its output format is much simpler and therefore easier to parse.

Answered By: user355252

For Windows

A Way to get all the pids of programs on your computer without downloading any modules:

import os

pids = []
a = os.popen("tasklist").readlines()
for x in a:
      try:
         pids.append(int(x[29:34]))
      except:
           pass
for each in pids:
         print(each)

If you just wanted one program or all programs with the same name and you wanted to kill the process or something:

import os, sys, win32api

tasklistrl = os.popen("tasklist").readlines()
tasklistr = os.popen("tasklist").read()

print(tasklistr)

def kill(process):
     process_exists_forsure = False
     gotpid = False
     for examine in tasklistrl:
            if process == examine[0:len(process)]:
                process_exists_forsure = True
     if process_exists_forsure:
         print("That process exists.")
     else:
        print("That process does not exist.")
        raw_input()
        sys.exit()
     for getpid in tasklistrl:
         if process == getpid[0:len(process)]:
                pid = int(getpid[29:34])
                gotpid = True
                try:
                  handle = win32api.OpenProcess(1, False, pid)
                  win32api.TerminateProcess(handle, 0)
                  win32api.CloseHandle(handle)
                  print("Successfully killed process %s on pid %d." % (getpid[0:len(prompt)], pid))
                except win32api.error as err:
                  print(err)
                  raw_input()
                  sys.exit()
    if not gotpid:
       print("Could not get process pid.")
       raw_input()
       sys.exit()

   raw_input()
   sys.exit()

prompt = raw_input("Which process would you like to kill? ")
kill(prompt)

That was just a paste of my process kill program I could make it a whole lot better but it is okay.

Answered By: user3818650

The task can be solved using the following piece of code, [0:28] being interval where the name is being held, while [29:34] contains the actual pid.

import os

program_pid = 0
program_name = "notepad.exe"

task_manager_lines = os.popen("tasklist").readlines()
for line in task_manager_lines:
    try:
        if str(line[0:28]) == program_name + (28 - len(program_name) * ' ': #so it includes the whitespaces
            program_pid = int(line[29:34])
            break
    except:
        pass

print(program_pid)
Answered By: Sand3r

Also:
Python: How to get PID by process name?

Adaptation to previous posted answers.

def getpid(process_name):
    import os
    return [item.split()[1] for item in os.popen('tasklist').read().splitlines()[4:] if process_name in item.split()]

getpid('cmd.exe')
['6560', '3244', '9024', '4828']
Answered By: DevPlayer

For posix (Linux, BSD, etc… only need /proc directory to be mounted) it’s easier to work with os files in /proc

Works on python 2 and 3 ( The only difference is the Exception tree, therefore the “except Exception“, which i dislike but kept to maintain compatibility. Also could’ve created custom exception.)

#!/usr/bin/env python

import os
import sys


for dirname in os.listdir('/proc'):
    if dirname == 'curproc':
        continue

    try:
        with open('/proc/{}/cmdline'.format(dirname), mode='rb') as fd:
            content = fd.read().decode().split('x00')
    except Exception:
        continue

    for i in sys.argv[1:]:
        if i in content[0]:
            # dirname is also the number of PID
            print('{0:<12} : {1}'.format(dirname, ' '.join(content)))

Sample Output (it works like pgrep):

phoemur ~/python $ ./pgrep.py bash
1487         : -bash 
1779         : /bin/bash
Answered By: Fernando

With psutil:

(can be installed with [sudo] pip install psutil)

import psutil

# Get current process pid
current_process_pid = psutil.Process().pid
print(current_process_pid)  # e.g 12971

# Get pids by program name
program_name = 'chrome'
process_pids = [process.pid for process in psutil.process_iter() if process.name == program_name]
print(process_pids)  # e.g [1059, 2343, ..., ..., 9645]
Answered By: Eyal Levin

This is a simplified variation of Fernando’s answer. This is for Linux and either Python 2 or 3. No external library is needed, and no external process is run.

import glob

def get_command_pid(command):
    for path in glob.glob('/proc/*/comm'):
        if open(path).read().rstrip() == command:
            return path.split('/')[2]

Only the first matching process found will be returned, which works well for some purposes. To get the PIDs of multiple matching processes, you could just replace the return with yield, and then get a list with pids = list(get_command_pid(command)).

Alternatively, as a single expression:

For one process:

next(path.split('/')[2] for path in glob.glob('/proc/*/comm') if open(path).read().rstrip() == command)

For multiple processes:

[path.split('/')[2] for path in glob.glob('/proc/*/comm') if open(path).read().rstrip() == command]
Answered By: Derek Veit
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.