Seite 1 von 1

process dupliziert sich immer wieder? (subprocess)

Verfasst: Samstag 6. Juni 2009, 18:10
von AngelusNoctis
Hallo

Ich hab hier ein sehr komisches Verhalten mit subprocess und keinen Plan obs an mir liegt.

Ich hab ein sehr einfaches script im run das mir beim login ein app startet.

Code: Alles auswählen

import subprocess, time

while True:
      try:
            subprocess.Popen('info.exe')
            time.sleep(5)
            exit()
      except:
            pass
Das seltsame ist jetzt, das sich info.exe jedesmal dupliziert!?
Nach wenigen Minuten hab ich 10 oder 20 info.exe im Taskmanger

Ist das verhalten normal oder hab ich irgendwas bei subprocess verpasst? oO

Verfasst: Samstag 6. Juni 2009, 18:25
von cofi
Warum steht das denn in einer while-Schleife?

Verfasst: Samstag 6. Juni 2009, 19:06
von AngelusNoctis
cofi hat geschrieben:Warum steht das denn in einer while-Schleife?

Das vollständige Script zieht noch mit urllib2 die Datei. Der Sinn der Schleife ist dass, das script nicht nach dem except beendet wäre sondern noch mal anfängt und erst "endet" wenn der try teil erfüllt ist.

Dachte der Schnippsel reicht weils NUR um subprocess geht. oO

Verfasst: Samstag 6. Juni 2009, 19:12
von lunar
Der Schnipsel reicht, um zu erkennen, dass du in einer Endlosschleife laufend neue Prozesse startest. Daher sollte es dich nicht wundern, wenn viele Prozesse auftauchen ...

Ein "except:" ohne Logging oder konkrete Ausnahme ist übrigens ziemlich schlechter Stil. Du fängst so alle Ausnahmen ab, auch z.B. durch Tippfehler NameError-Ausnahmen. Entweder solltest du eine konkrete Ausnahme in den "except"-Ausdruck aufnehmen, und am besten noch in einem Kommentar begründen, warum du diese Ausnahme ignorierst, oder du solltest wenigstens das "logging"-Modul dazu nutzen, den Traceback zu erhalten, damit man das Skript noch debuggen kann.

Verfasst: Samstag 6. Juni 2009, 19:29
von AngelusNoctis
lunar hat geschrieben:Der Schnipsel reicht, um zu erkennen, dass du in einer Endlosschleife laufend neue Prozesse startest. Daher sollte es dich nicht wundern, wenn viele Prozesse auftauchen ...

Ein "except:" ohne Logging oder konkrete Ausnahme ist übrigens ziemlich schlechter Stil. Du fängst so alle Ausnahmen ab, auch z.B. durch Tippfehler NameError-Ausnahmen. Entweder solltest du eine konkrete Ausnahme in den "except"-Ausdruck aufnehmen, und am besten noch in einem Kommentar begründen, warum du diese Ausnahme ignorierst, oder du solltest wenigstens das "logging"-Modul dazu nutzen, den Traceback zu erhalten, damit man das Skript noch debuggen kann.

Aber da ich das Script mit exit() beende (falls erfolgreich) wäre doch die Schleife hinfällig?!

Der Prozess des "mini-script" findet sich dann auch nimmer im Taskmanager.

Hab jetzt anstelle von exit() break genommen, jetzt gehts.

Trotzdem frag ich mich wieso exit() das ganze zwar schliesst aber es anscheinend weiterläuft. oO

Verfasst: Samstag 6. Juni 2009, 19:40
von lunar
Mal abgesehen davon, dass du besser direkt "sys.exit()" nutzt, beendet sich dein Skript nicht. "sys.exit()" löst eine "SystemExit"-Ausnahme aus, um den Python-Interpreter zu beendet, und diese Ausnahme wird von deinem "except:" stillschweigend verschluckt. Das steht im Übrigen auch in der Dokumentation, und ist noch ein Grund, warum man niemals ein "except:" ohne konkrete Ausnahme nutzt, wenn man nicht wirklich jede Ausnahme abfangen möchte.

Verfasst: Samstag 6. Juni 2009, 19:55
von AngelusNoctis
lunar hat geschrieben:Mal abgesehen davon, dass du besser direkt "sys.exit()" nutzt, beendet sich dein Skript nicht. "sys.exit()" löst eine "SystemExit"-Ausnahme aus, um den Python-Interpreter zu beendet, und diese Ausnahme wird von deinem "except:" stillschweigend verschluckt. Das steht im Übrigen auch in der Dokumentation, und ist noch ein Grund, warum man niemals ein "except:" ohne konkrete Ausnahme nutzt, wenn man nicht wirklich jede Ausnahme abfangen möchte.

Also bisher ist mir das nie untergekommen, dass ein Except auswirkung hat wenn der try funktioniert.

Ich ging auch immer davon aus das except ignoriert wird wenn try klappt, was ja auch irgendwie logisch ist.


Naja, seis drum.

Ich dank euch beiden :)

Verfasst: Samstag 6. Juni 2009, 19:56
von BlackJack
Insbesondere verschluckt man hier mit einem ``except`` ohne konkrete Ausnahme auch den `NameError`, der einem verraten hätte, dass es die Funktion `exit()` nicht gibt.

Das heisst Du bekommst gar nicht mit ob das im ``try``-Block nun funktioniert hat oder nicht.

Verfasst: Samstag 6. Juni 2009, 20:00
von Leonidas
AngelusNoctis hat geschrieben:Ich ging auch immer davon aus das except ignoriert wird wenn try klappt, was ja auch irgendwie logisch ist.
Aber dein try-Block klappt eben nicht, weil ``exit()`` eine Exception wirft.

Verfasst: Samstag 6. Juni 2009, 21:10
von lunar
BlackJack hat geschrieben:Insbesondere verschluckt man hier mit einem ``except`` ohne konkrete Ausnahme auch den `NameError`, der einem verraten hätte, dass es die Funktion `exit()` nicht gibt.
"exit()" gibt es. "site.py" ruft beim Importieren "site.setquit()" auf, welches ein Exemplar der lokalen Klasse "Quitter" an die Builtin-Namen "exit" und "quit" bindet. Der __call__-Operator dieser Klasse schließt "sys.stdin" und ruft "sys.exit()" auf.

Das Ding ist eigentlich für den interaktiven Modus gedacht, denn sein "__repr__()" sorgt für die Meldung, die erscheint, wenn man im interaktiven Modus "exit" eingibt.

Dokumentiert ist das allerdings nicht, daher sollte man es selbstverständlich auch nicht nutzen.

Verfasst: Samstag 6. Juni 2009, 21:52
von BlackJack
@lunar: Okay, `exit` mag es geben, aber es muss nicht ausführbar sein:

Code: Alles auswählen

bj@s8n:~$ python2.4 -c "exit()"
Traceback (most recent call last):
  File "<string>", line 1, in ?
TypeError: 'str' object is not callable

Verfasst: Samstag 6. Juni 2009, 21:58
von cofi
Kommt auf die Version an ;)

Code: Alles auswählen

$ python2.5 -c "exit()"
$ python2.6 -c "exit()"

Verfasst: Sonntag 7. Juni 2009, 09:33
von AngelusNoctis
K

Wieder bisschen schlauer XD

Danke :)

Verfasst: Samstag 20. Juni 2009, 20:07
von lunar
lunar hat geschrieben:[...]Dokumentiert ist das allerdings nicht, daher sollte man es selbstverständlich auch nicht nutzen.
Nachtrag: "exit()" ist doch dokumentiert, aber mit dem klaren Hinweis, es in Programme nicht zu benutzen.