Kann ich den effektiven Prozessnamen eines Python-Skripts ändern? Ich möchte einen anderen Namen anstelle des tatsächlichen Namens des Prozesses anzeigen, wenn ich die Systemprozessliste erhalte. In CI kann eingestellt werden
strcpy(argv[0],"othername");
Aber in Python
argv[0] = "othername"
scheint nicht zu funktionieren. Wenn ich eine Prozessliste bekomme (mit ps ax
in meiner Linux-Box), ändert sich der wirkliche Name nicht. Ich bevorzuge eine tragbare Lösung (oder eine Lösung für posix und eine andere für Windows-Umgebungen), falls vorhanden.
Danke im Voraus
Antworten:
Einfach gesagt, es gibt keinen tragbaren Weg. Sie müssen das System testen und die bevorzugte Methode für dieses System verwenden.
Außerdem bin ich verwirrt darüber, was Sie unter Prozessnamen unter Windows verstehen.
Meinen Sie einen Servicenamen? Ich nehme das an, weil nichts anderes wirklich Sinn macht (zumindest für mein Nicht-Windows-Gehirn).
In diesem Fall müssen Sie die WMI-Schnittstelle von Tim Golden verwenden und die .Change-Methode für den Dienst aufrufen ... zumindest gemäß seinem Tutorial .
Unter Linux funktionierte keine der Methoden, die ich gefunden habe, außer diesem schlecht gepackten Modul , das argv [0] für Sie festlegt.
Ich weiß nicht einmal, ob dies bei BSD-Varianten funktioniert (die einen Systemaufruf setproctitle haben). Ich bin mir ziemlich sicher, dass argv [0] unter Solaris nicht funktioniert.
quelle
Ich habe kürzlich ein Python-Modul geschrieben, um den Prozesstitel auf tragbare Weise zu ändern: Überprüfen Sie https://github.com/dvarrazzo/py-setproctitle
Es ist ein Wrapper um den Code, der von PostgreSQL verwendet wird, um die Titeländerung durchzuführen. Es wird derzeit gegen Linux und Mac OS X getestet: Windows (mit eingeschränkter Funktionalität) und BSD-Portierungen sind unterwegs.
Bearbeiten: Ab Juli 2010 arbeitet das Modul mit BSD und mit eingeschränkter Funktionalität unter Windows und wurde auf Python 3.x portiert.
quelle
Eigentlich brauchst du 2 Dinge unter Linux: Ändern
argv[0]
vonC
(fürps auxf
und Freunde) und Aufrufenprctl
mitPR_SET_NAME
Flag.Es gibt absolut keine Möglichkeit, das erste Stück aus Python selbst zu machen. Sie können den Prozessnamen jedoch einfach ändern, indem Sie prctl aufrufen.
def set_proc_name(newname): from ctypes import cdll, byref, create_string_buffer libc = cdll.LoadLibrary('libc.so.6') buff = create_string_buffer(len(newname)+1) buff.value = newname libc.prctl(15, byref(buff), 0, 0, 0) def get_proc_name(): from ctypes import cdll, byref, create_string_buffer libc = cdll.LoadLibrary('libc.so.6') buff = create_string_buffer(128) # 16 == PR_GET_NAME from <linux/prctl.h> libc.prctl(16, byref(buff), 0, 0, 0) return buff.value import sys # sys.argv[0] == 'python' # outputs 'python' get_proc_name() set_proc_name('testing yeah') # outputs 'testing yeah' get_proc_name()
ps auxf
zeigt danach nur noch 'Python' an :(. Abertop
undps -A
zeigt den neuen Prozessnamen 'testing yeah' an :). Auchkillall
undpkill
wird mit neuem Namen arbeiten.Übrigens ändert sich auch der Procname von Google Code
argv[0]
und damit sogar dieps auxf
Ausgabe.UPDATE : Die in dieser Antwort veröffentlichte Lösung funktioniert unter FreeBSD manchmal nicht gut. Ich verwende jetzt py-setproctitle , das in dieser Antwort angegeben ist, für ungefähr ein Jahr auf verschiedenen Linux- und Freebsd-Boxen. Nein scheitert bisher! Jeder sollte auch! :). Er verwendet fast den gleichen Code wie PostgreSQL verwendet in seiner Hauptdatenbank und Kindprozesse.
quelle
Schauen Sie sich das setproctitle- Paket an
Dies ist eine ziemlich tragbare Version und funktioniert auf vielen Plattformen.
import setproctitle setproctitle.setproctitle('new proc title as seen in top')
quelle
Erstens bin ich mir nicht sicher, ob einfache Einstellungen
argv[0]
in einem C-Programm den Namen in ändernps
. Vielleicht tut es in einigen Unixen, aber ich verstehe, dass es nicht erwartet wird.Zweitens, da Windows speziell nicht POSIX-kompatibel ist, sind nur wenige Dinge zwischen POSIX und Nicht-POSIX "portabel". Da Sie ausdrücklich "ps" sagen, gehe ich davon aus, dass POSIX Ihre Priorität ist und Windows möglicherweise nicht funktioniert.
Noch wichtiger ist, dass ich verstehe,
argv[0]
dass Änderungen erforderlich sindexec
, um diese Änderungen vorzunehmen. Insbesondere hat derexec
Aufruf sowohl einen Pfad zu einer ausführbaren Datei als auch eine separateargv
Liste. Wenn Sie Ihren eigenen Anruf tätigen, können Sie die Shell-Konvention zum Einfügen des ausführbaren Namens brechenargv[0]
.Sie verfügen über eine Prozessverwaltung für die Betriebssystembibliothek, mit der Sie direkt auf die Betriebssystembibliothek zugreifen können. Sie sollten in Betracht ziehen, Ihr Skript in zwei Teile zu teilen - einen Starter und die "echte Arbeit". Der Starter legt die Laufzeitumgebung fest und führt die eigentliche Arbeit mit den gewünschten Parametern aus.
In C ersetzen Sie Ihren eigenen Prozess durch einen anderen. In Python ersetzen Sie den alten Python-Interpreter durch einen neuen mit einem anderen Argument [0]. Hoffentlich wird es das nicht verhindern. Einige Programme überprüfen argv [0], um zu entscheiden, was sie tun.
Sie haben auch subprocess.popen , mit dem Sie die gewünschten Argumente und die ausführbare Datei festlegen können. In diesem Fall sollte der übergeordnete Prozess jedoch verweilen, um das Kind zu sammeln, wenn das Kind fertig ist. Der Elternteil darf nicht mehr als a tun
Popen.wait
quelle
Meine Antwort auf eine ähnliche Frage, die als Duplikat markiert ist :
Es ist einfacher (Sie müssen keine Bibliotheken importieren), aber vielleicht nicht so elegant. Sie müssen "env" nicht innerhalb der Shebang-Linie verwenden.
Mit anderen Worten, dies wird in der Prozessliste als "Python" bezeichnet:
#!/usr/bin/env python
Dies wird jedoch mit Ihrem Skriptnamen benannt:
#!/usr/bin/python
So können Sie es mit so etwas wie
pidof -x scriptname
oder findenps -C scriptname
quelle
Ich habe festgestellt, dass Python-Prctl unter Linux sehr gut funktioniert. Sie müssen etwas anderes für Windows finden.
quelle
In [1]: import sys In [2]: print sys.argv[0] C:\Python25\scripts\ipython.py In [3]: sys.argv[0] = 'foo' In [4]: print sys.argv[0] foo
Beachten Sie das einzelne '=' Zeichen
quelle