17

How do I get a process list of all running processes from Python, on Unix, containing then name of the command/process and process id, so I can filter and kill processes.

oHo
  • 51,447
  • 27
  • 165
  • 200
Johan Carlsson
  • 743
  • 3
  • 11
  • 24
  • Are you filtering for anything specific in the process name? or just filtering for the process ids that match the process name? – nik Jul 07 '09 at 10:05
  • I need to match up some streaming session in Darwin Streaming Server that doesn't have any current listeners, with the process providing the stream. Some one mentioned pgrep/pkill which also would be useful, but I think I'll use krawyoti and do os.kill from python, I'm just more comfortable writing python code then using shell commands. – Johan Carlsson Jul 07 '09 at 17:24

5 Answers5

26

The right portable solution in Python is using psutil. You have different APIs to interact with PIDs:

>>> import psutil
>>> psutil.pids()
[1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, ..., 32498]
>>> psutil.pid_exists(32498)
True
>>> p = psutil.Process(32498)
>>> p.name()
'python'
>>> p.cmdline()
['python', 'script.py']
>>> p.terminate()
>>> p.wait()

...and if you want to "search and kill":

for p in psutil.process_iter():
    if 'nginx' in p.name() or 'nginx' in ' '.join(p.cmdline()):
        p.terminate()
        p.wait()
Giampaolo Rodolà
  • 12,488
  • 6
  • 68
  • 60
12

On Linux, with a suitably recent Python which includes the subprocess module:

from subprocess import Popen, PIPE

process = Popen(['ps', '-eo' ,'pid,args'], stdout=PIPE, stderr=PIPE)
stdout, notused = process.communicate()
for line in stdout.splitlines():
    pid, cmdline = line.split(' ', 1)
    #Do whatever filtering and processing is needed

You may need to tweak the ps command slightly depending on your exact needs.

nosklo
  • 217,122
  • 57
  • 293
  • 297
Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
2

On linux, the easiest solution is probably to use the external ps command:

>>> import os
>>> data = [(int(p), c) for p, c in [x.rstrip('\n').split(' ', 1) \
...        for x in os.popen('ps h -eo pid:1,command')]]

On other systems you might have to change the options to ps.

Still, you might want to run man on pgrep and pkill.

krawyoti
  • 19,695
  • 1
  • 23
  • 17
  • pgrep/pkill looks like a good solution for what I need (at least this time). I've always missed a built in ps function in Python, so that's part of the reason I posted this question. Cheers – Johan Carlsson Jul 07 '09 at 11:32
  • 2
    os.popen is deprecated. Use the subprocess module. – nosklo Jul 08 '09 at 11:35
  • 1
    Huh, this is interesting. It's worth a question on its own: http://stackoverflow.com/questions/1098257 – krawyoti Jul 08 '09 at 13:59
0

Install psutil:

$pip install psutil

Import psutil:

>>> import psutil

Define list where process list is to be saved:

>>> processlist=list()

Append processes in list:

>>> for process in psutil.process_iter():
        processlist.append(process.name())

Get Process list:

>>> print(processlist)

Full code:

import psutil
processlist=list()
for process in psutil.process_iter():
    processlist.append(process.name())
print(processlist)
-9

Why Python?
You can directly use killall on the process name.

nik
  • 13,254
  • 3
  • 41
  • 57
  • he said he would filter and then kill – Umair Ahmed Jul 07 '09 at 09:55
  • Good observation, but why filter the `ps` output for the command name, gather process id values and then kill, when the `killall` does it for you? – nik Jul 07 '09 at 09:57
  • because I need to match up the processes with other data. – Johan Carlsson Jul 07 '09 at 11:29
  • I am retaining this answer because it highlights the need for a ithin-python solution. The question has no need for the `kill` part; it can be simply, `how do I get the process list in Python?` – nik Jun 30 '11 at 13:31