Prozess-IDs (PIDs) und den Namen laufender Prozesse

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi @all!

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
"""
Returns processinfos. (pid, name and size_kb)

Free for everybody. (by gerold)
"""

import sys
import os


def get_current_processes():
    """
    Returns processinfos. (pid, name and size_kb)

    On Windows-Systems, it uses ``tasklist.exe`` or WMI to list the processes.
    On other platforms, it reads the "/proc"-directory.
    
    :return: Dictionary with PID's as keys and the infos as values in an
        inner dictionary. (It is possible, that "size_kb" doesn't exist.): 
        {
            123: {"name": "bash", "pid": 123},
            234: {"name": "mc", "pid": 234, "size_kb": 1000},
        }
    """
    
    retdict = {}
    
    if sys.platform.startswith("win"):
        # tasklist.exe runs on Windows XP and higher. (To parse the ouput of
        # tasklist.exe is faster than WMI.)
        import csv
        csvlines = []
        for line in os.popen("tasklist.exe /fo csv /nh"):
            line = line.strip()
            if line:
                csvlines.append(line)
        for line in csv.reader(csvlines):
            pid = int(line[1])
            details = {
                "name": line[0].decode("cp850"), # to unicode
                "pid": pid,
            }
            value = "".join(
                char for char in line[4]
                if char in "0123456789"
            )
            details["size_kb"] = int(value)
            retdict[pid] = details
        if not csvlines:
            try:
                from win32com.client import GetObject
                # pywin32 is installed --> use WMI
                wmi = GetObject('winmgmts:')
                processes = wmi.InstancesOf('Win32_Process')
                for process in processes:
                    pid = int(process.Properties_("ProcessId").value)
                    details = {
                        "name": process.Properties_("Name").value,
                        "pid": pid,
                        "size_kb": int(process.Properties_("WorkingSetSize").value) / 1000
                    }
                    retdict[pid] = details
            except ImportError:
                raise NotImplementedError("No tasklist.exe and no WMI.")
    else:
        # Linux, Cygwin
        from glob import glob
        for filename in glob("/proc/*/status"):
            try: 
                int(filename[len("/proc/"):-len("/status")])
            except ValueError:
                continue
            details = {}
            try:
                f = file(filename, "r")
                try:
                    for line in f:
                        line_lower = line.lower()
                        if line_lower.startswith("name:"):
                            details["name"] = line[len("Name:"):].strip()
                        elif line_lower.startswith("pid:"):
                            details["pid"] = line[len("pid:"):].strip()
                        elif line_lower.startswith("vmsize:"):
                            value = "".join(
                                char for char in line[len("vmsize:"):]
                                if char in "0123456789"
                            )
                            details["size_kb"] = int(value)
                        if (
                            details.has_key("name") and
                            details.has_key("pid") and
                            details.has_key("size_kb")
                        ):
                            break
                finally:
                    f.close()
            except IOError:
                pass
            if details:
                retdict[details["pid"]] = details
    
    # Return value
    return retdict or None


def main():
    """Testing"""
    
    from pprint import pformat

    # Process-Infos
    print pformat(get_current_processes())
    

if __name__ == "__main__":
    main()
Siehe auch: http://www.python-forum.de/topic-8277.html
Trac: http://gelb.bcom.at/trac/misc/browser/processinfo

lg
Gerold
:-)
Zuletzt geändert von gerold am Freitag 19. Januar 2007, 19:34, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

...jetzt auch mit WMI. :-)
(dank dem Link von Leonidas)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Super!
Ist nun, wie das vorherige Script von dir, in meiner Library 8)

Wenns dir nichts ausmacht, könntest du ja im Wiki einen Link zu diesem Thread und den anderen packen, weil man dein Script immer mal gebrauchen kann :)

lg
xraver
User
Beiträge: 4
Registriert: Dienstag 8. Mai 2007, 11:36
Wohnort: Germany

Hallo,
das Script funktioniert wunderbar.
Für mein Projekt möchte ich einfach nur überprüfen ob ein bestimmter Process vorhanden ist. Wie kann ich das Ergebnis deines Scripts (oder eines Dictionary) durchsuchen?

//update
Jetzt habe ich es erstmal so gemacht um einen gewünschten Process zu finden;

Code: Alles auswählen

str(get_current_processes()).find('firefox.exe')
Aber es gibt doch bestimmt noch eine saubere Lösung, oder?
BigBo
User
Beiträge: 18
Registriert: Mittwoch 5. September 2007, 13:16
Wohnort: Friedrichshafen
Kontaktdaten:

hi gerold!

dein code ist wirklich super !

aber wie bekomm ich da aus der liste wo er mir zurückliefert die pid eines bestimmten prozesses ?

ps: ich habs mal so versucht:

Code: Alles auswählen

pid2 = fileOps.get_current_processes()
pid = str(fileOps.get_current_processes()).find('fpassist.exe')
print pid
print pid2
allerdings kam mir dann folgende ausgabe:
261
..."1004: {'pid': 1004, 'name': u'fpassist.exe', 'size_kb': 1028}"...

also hat der prozess fpassist.exe im moment die pid 1004, aber mit dem find bekomm ich 261 zurück (die position im dictionary?)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

BigBo hat geschrieben:wie bekomm ich da aus der liste wo er mir zurückliefert die pid eines bestimmten prozesses ?
Hallo BigBo!

Nachdem ich deine Frage entschlüsselte... :?

Erstens:
Du bekommst **keine Liste** sondern ein **Dictionary** zurück.

Zweitens:
Z.B. so:

Code: Alles auswählen

processes = {
    0: {'name': u'System Idle Process', 'pid': 0, 'size_kb': 16},
    4: {'name': u'System', 'pid': 4, 'size_kb': 220},
    264: {'name': u'IAAnotif.exe', 'pid': 264, 'size_kb': 2112},
    268: {'name': u'sqlservr.exe', 'pid': 268, 'size_kb': 178548},
}

for proc in processes.values():
    if proc["name"] == "IAAnotif.exe":
        # Gefunden
        print proc["name"]
        print proc["pid"]
        break
else:
    print "Nichts gefunden"
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BigBo
User
Beiträge: 18
Registriert: Mittwoch 5. September 2007, 13:16
Wohnort: Friedrichshafen
Kontaktdaten:

*lach* sorry das meine frage so undeutlich formuliert war gerold, versuch mich in zukunft zu bessern, danke es funktioniert so :-)
BigBo
User
Beiträge: 18
Registriert: Mittwoch 5. September 2007, 13:16
Wohnort: Friedrichshafen
Kontaktdaten:

ähm...nochmal n sonderwunsch gerold :oops: kann man noch irgendwie in des dictionary einbauen, das es unter windows anzeigt, welcher benutzer einen prozess gestartet hat?
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Auch noch eine Frage/ein Wunsch von mir: Ist es möglich, dass nicht nur der Dateiname des Prozesses aufgelistet wird, sondern auch der komplette Pfad zur Datei?

Und das mit dem Besitzer des Prozesses (Benutzername) wäre auch ne feine und wichtige Sache, um zu unterscheiden ob es sich um einen Systemprozess handelt oder einen Userprozess. Unter Windows ist das bestimmt recht einfach ermittelbar -> Wie sieht es bei Unix aus?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

In Linux gehört der zur PID gehörende Ordner in `/proc` dem ausführendem User.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Wenn ich es richtig verstehe, hat jede PID einen gleichnamigen Ordner. Also der Prozess mit der ID 123 hat den Ordner /proc/123, richtig? Dort drin lagert jede Menge Unkraut, was ich aber leider nicht zuordnen kann. Ist auch nicht ganz so wichtig...

Was mich aber interessiert: ich habe z.B. zwei gleichnamige Dateien in /foo/bar und die andere in /bar/bar. Ich führe nun beide aus. /foo/bar bekommt PID 1234 und /bar/bar bekommt PID 5678. Über Gerolds Tool kann bekomme ich ein Dictionary mit den Infos:

Code: Alles auswählen

{
    "1234": "bar",
    "5678": "bar"
}
Das ist jetzt nur sinngemäß, ihr versteht... Ich kann anhand der Prozessliste nicht unterscheiden, welche der beiden Dateien welche ist, weil beide denselben Namen tragen. Daher wäre es für mich wichtig, auch den vollständigen Pfad zur ausgeführten Datei zu kennen, um sie eindeutig zu identifizieren.

Wie könnte man den vollständigen Pfad heraus bekommen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

droptix hat geschrieben:Wie könnte man den vollständigen Pfad heraus bekommen?
Der Symlink `'/proc/%s/cmd' % PID` zeigt auf die entsprechende ausgeführte Datei. Du kannst sogar noch so einen Prozess damit starten, etwa so:

Code: Alles auswählen

$ /proc/$(pidof firefox-bin)/exe
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Prima! Aber ich finde nirgends /proc/PID/cmd, meinst du vielleicht /proc/PID/cwd?

Ich befinde mich im Verzeichnis /proc/1249, welches mir gehört. Dort drin liegt folgendes:
droptix@hostname:/proc/1249$ ls -la
ls: cannot read symbolic link cwd: Permission denied
ls: cannot read symbolic link root: Permission denied
ls: cannot read symbolic link exe: Permission denied
total 0
dr-xr-xr-x 6 droptix droptix 0 2007-12-12 08:53 .
dr-xr-xr-x 82 root root 0 2007-12-04 18:29 ..
dr-xr-xr-x 2 droptix droptix 0 2007-12-12 08:55 attr
-r-------- 1 root root 0 2007-12-12 08:55 auxv
--w------- 1 root root 0 2007-12-12 08:55 clear_refs
-r--r--r-- 1 root root 0 2007-12-12 08:55 cmdline
-r--r--r-- 1 root root 0 2007-12-12 08:55 cpuset
lrwxrwxrwx 1 root root 0 2007-12-12 08:55 cwd
-r-------- 1 root root 0 2007-12-12 08:55 environ
lrwxrwxrwx 1 root root 0 2007-12-12 08:55 exe
dr-x------ 2 root root 0 2007-12-12 08:55 fd
dr-x------ 2 root root 0 2007-12-12 08:55 fdinfo
-r--r--r-- 1 root root 0 2007-12-12 08:55 maps
-rw------- 1 root root 0 2007-12-12 08:55 mem
-r--r--r-- 1 root root 0 2007-12-12 08:55 mounts
-r-------- 1 root root 0 2007-12-12 08:55 mountstats
-rw-r--r-- 1 root root 0 2007-12-12 08:55 oom_adj
-r--r--r-- 1 root root 0 2007-12-12 08:55 oom_score
lrwxrwxrwx 1 root root 0 2007-12-12 08:55 root
-rw------- 1 root root 0 2007-12-12 08:55 seccomp
-r--r--r-- 1 root root 0 2007-12-12 08:55 smaps
-r--r--r-- 1 root root 0 2007-12-12 08:55 stat
-r--r--r-- 1 root root 0 2007-12-12 08:55 statm
-r--r--r-- 1 root root 0 2007-12-12 08:55 status
dr-xr-xr-x 3 droptix droptix 0 2007-12-12 08:55 task
-r--r--r-- 1 root root 0 2007-12-12 08:55 wchan
droptix@hostname:/proc/1249$
Die Symlinks cwd, root und exe darf ich nicht lesen. Also bekomme ich den Pfad nur mit root-Rechten raus... aber das lässt sich ja einrichten. Sieht dann so aus:
droptix@hostname:/proc/1249$ sudo ls -la
total 0
dr-xr-xr-x 6 droptix droptix 0 2007-12-12 08:53 .
dr-xr-xr-x 82 root root 0 2007-12-04 18:29 ..
dr-xr-xr-x 2 droptix droptix 0 2007-12-12 08:55 attr
-r-------- 1 root root 0 2007-12-12 08:55 auxv
--w------- 1 root root 0 2007-12-12 08:55 clear_refs
-r--r--r-- 1 root root 0 2007-12-12 08:55 cmdline
-r--r--r-- 1 root root 0 2007-12-12 08:55 cpuset
lrwxrwxrwx 1 root root 0 2007-12-12 08:55 cwd -> /
-r-------- 1 root root 0 2007-12-12 08:55 environ
lrwxrwxrwx 1 root root 0 2007-12-12 08:55 exe -> /usr/sbin/sshd
dr-x------ 2 root root 0 2007-12-12 08:55 fd
dr-x------ 2 root root 0 2007-12-12 08:55 fdinfo
-r--r--r-- 1 root root 0 2007-12-12 08:55 maps
-rw------- 1 root root 0 2007-12-12 08:55 mem
-r--r--r-- 1 root root 0 2007-12-12 08:55 mounts
-r-------- 1 root root 0 2007-12-12 08:55 mountstats
-rw-r--r-- 1 root root 0 2007-12-12 08:55 oom_adj
-r--r--r-- 1 root root 0 2007-12-12 08:55 oom_score
lrwxrwxrwx 1 root root 0 2007-12-12 08:55 root -> /
-rw------- 1 root root 0 2007-12-12 08:55 seccomp
-r--r--r-- 1 root root 0 2007-12-12 08:55 smaps
-r--r--r-- 1 root root 0 2007-12-12 08:55 stat
-r--r--r-- 1 root root 0 2007-12-12 08:55 statm
-r--r--r-- 1 root root 0 2007-12-12 08:55 status
dr-xr-xr-x 3 droptix droptix 0 2007-12-12 08:55 task
-r--r--r-- 1 root root 0 2007-12-12 08:55 wchan
Ich denke der Symlink exe zeigt auf die Datei und cwd wahrscheinlich auf das Current Working Directory, oder? Was bedeuted root?
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

droptix hat geschrieben:Ich denke der Symlink exe zeigt auf die Datei und cwd wahrscheinlich auf das Current Working Directory, oder?
Yepp.
droptix hat geschrieben:Was bedeuted root?
Das ist das Wurzelverzeichnis.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

droptix hat geschrieben:Prima! Aber ich finde nirgends /proc/PID/cmd, meinst du vielleicht /proc/PID/cwd?
Nein, ich meine so wie ich geschrieben habe `exe`. Und bei mir ist die User-lesbar, zumindest für den der sie gestartet hat. Was hast du für ein System? Distribution und Kernel?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Rebecca hat geschrieben:
droptix hat geschrieben:Was bedeuted root?
Das ist das Wurzelverzeichnis.
:twisted: LOL!

Ist denn root nicht immer /, weil man das hier extra auflistet? Aber das tut wenig zur Sache... ich weiß jetzt alles um mir Gerolds Script etwas anzupassen. Danke!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Es kann ja sein, dass das Programm in einem Chroot läuft da etwas anderes steht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Leonidas hat geschrieben:Der Symlink `'/proc/%s/cmd' % PID` zeigt auf die entsprechende ausgeführte Datei.
^^ Du sagtest cmd, daher die Verwirrung.
Leonidas hat geschrieben:
droptix hat geschrieben:Prima! Aber ich finde nirgends /proc/PID/cmd, meinst du vielleicht /proc/PID/cwd?
Nein, ich meine so wie ich geschrieben habe `exe`. Und bei mir ist die User-lesbar, zumindest für den der sie gestartet hat. Was hast du für ein System? Distribution und Kernel?
Habe Ubuntu Linux 7.10 (Gutsy). Bei mir war die nicht User-lesbar.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Gah, hast recht. :evil: Ich war absolut überzeugt, dass ich `exe` geschrieben habe.

Gut, was hat denn Gutsy für einen Kernel und was für eine glibc?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten