Prozess-IDs (PIDs) und den Namen laufender Prozesse

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

Prozess-IDs (PIDs) und den Namen laufender Prozesse

Beitragvon gerold » Freitag 19. Januar 2007, 15:06

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: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 19. Januar 2007, 15:50

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

Beitragvon sape » Freitag 19. Januar 2007, 16:13

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

Beitragvon xraver » Samstag 28. Juli 2007, 16:12

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?
lunar

Beitragvon lunar » Samstag 28. Juli 2007, 17:28

http://cheeseshop.python.org/pypi/enumprocess/0.1

Wieso wird das Rad eigentlich immer neu erfunden? ;)
BigBo
User
Beiträge: 18
Registriert: Mittwoch 5. September 2007, 13:16
Wohnort: Friedrichshafen
Kontaktdaten:

Beitragvon BigBo » Donnerstag 6. September 2007, 12:42

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: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Donnerstag 6. September 2007, 13:44

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:

Beitragvon BigBo » Donnerstag 6. September 2007, 14:11

*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:

Beitragvon BigBo » Freitag 7. September 2007, 11:51

ä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

Vollständiger Pfad

Beitragvon droptix » Dienstag 11. Dezember 2007, 09:11

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?
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 11. Dezember 2007, 12:32

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 Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Beitragvon droptix » Dienstag 11. Dezember 2007, 23:19

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?
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 11. Dezember 2007, 23:36

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=]$ /proc/$(pidof firefox-bin)/exe[/code]
My god, it's full of CARs! | Leonidasvoice vs Modvoice
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Beitragvon droptix » Mittwoch 12. Dezember 2007, 09:03

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:

Beitragvon Rebecca » Mittwoch 12. Dezember 2007, 09:16

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

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder