Seite 1 von 1

Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 09:43
von lill
Hallo,

habe folgendes Problem.
Mein Vorgängerpraktikant sollte damals ein Backupscript schreiben. Ist alles ganz "toll" und so, nur terminiert es nicht.
Wenn ich es mittels "./clientbackup.py" aufrufe, terminiert es ohne Probleme.
Jedoch bei "python clientbackup.py", mag das Script nicht zu ende laufen.
Nach "tausenden" print-Ausgaben habe ich herausgefunden, dass es am os._exit(0) lag (mit dem ich die Kindsprozesse beenden wollte).
Nachdem ich os._exit(0) in os.EX_OK geändert habe, lief das Script ein Stück weiter und blieb bei sys.exit(0) hängen.

Grob aufgebaut ist das Script wie folgt:

Code: Alles auswählen

import os, sys
def main():
  try:
    ...
    pid = os.fork()
    if pid == 0:
      ...
      os.EX_OK
    else:
      ...
    ...
    print "bis hierher geht alles"
    sys.exit(0)
  except KeyError:
    ...
  except KeyboardInterrupt:
    ...
    sys.exit(1)

if __name__ == "__main__":
  main()
Folgendes habe ich noch ausprobiert:
* sys.exit(0) hinter die try-Anweisung -> kein Unterschied
* zusätzlich noch ein except SystemExit, e: sys.exit(e) -> kein Unterschied
* mit python -v ausgeführt -> cleanup main läuft durch
-> bei cleanup sys bleibt's hängen
# cleanup sys
# cleanup __builtin__
# cleanup ints: 39 unfreed ints in 4 out of 19 blocks
# cleanup floats: 30 unfreed floats in 1 out of 3 blocks

Weitere Infos:
python -V
Python 2.4.3
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.6 (Tikanga)

Wäre echt nett, wenn mir jemand weiterhelfen könnte.

Grüße lill

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 10:36
von Dauerbaustelle
Bin mir nicht sicher, ob das jetzt auf die Beschreibung passt, aber du musst den Fork manuell terminieren (ein SIGTERM-Signal hinschicken oder zur Not SIGKILL), sollte er das nicht irgendwann selbst tun.

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 10:44
von lunar
Zeige bitte ein minimalen, lauffähigen Quelltext, der das Problem reproduziert, ohne irgendwelche Auslassungen und Mutmaßungen darüber, wo der Fehler liegen könnte.

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 10:44
von lill
@Dauerbaustelle
Sorry, da ich davon ausgegangen bin, dass das nicht das Problem sei, habe ich den Teil aus meinem "Codebeispiel" rausgelassen:

Code: Alles auswählen

def killAllChilds(childIDs):
  name=sys.argv[0].lstrip('./')
  name=name[0:15]
  proc_table=commands.getoutput('ps -a').split('\n')
  for childID in childIDs:
    for line in proc_table:
      if line.startswith(str(childID)) and line.count(name) > 0:
        os.kill(childID,signal.SIGKILL)
Viele Grüße lill

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 10:56
von ts7343
ist vielleicht nicht besonders originell, aber wenn es keiner sonst merkt,
dann hold dir die process ids als STDOUT mit subprocess rein und kill sie dann,

ps -fu <user_name> | grep python

kill -9 <process_id>

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 11:03
von Dauerbaustelle
Das Problem liegt vermutlich eh woanders.

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 11:34
von lill
So, ist nicht ganz so minimal geworden, aber das Problem ließ sich nicht so einfach "nachbauen".

http://pastebin.com/KuMDRNsh

Grüße lill

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 12:08
von lill
hab das Problem gefunden. Endlosschleife.

Also, das Problem:
Aufruf über
./clientbackup.py -> funktioniert
python clientbackup.py -> funktioniert nicht

Begründung:
Wenn ich das Script mittels ./clientbackup.py aufrufe, heißt der Prozess clientbackup.
Wenn ich das Script mittels python clientbackup.py aufrufe, heißt der Prozess python.

Da ich nach dem Namen des Scripts in der Prozessliste suchen, wird beim oberen Aufruf der Eintrag in der Prozessliste gefunden und beendet.
Beim unteren dementsprechend nicht.

Danke für die Hilfe
Gruß lill

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 17:09
von b.esser-wisser
Reicht ein einfaches 'os.wait()' am Ende des Elternprozesses nicht aus (Vorrausgesetzt deine fork's laufen nicht unendlich lang).

Alternativ tuts doch sowas:

Code: Alles auswählen

for child_id in child_ids: #gibt's wirklich mehr als ein 'child'?
    os.kill(child_id, signal.SIGKILL) # SIGTERM reicht nicht?
hth, Jörg

ps.: Wenn irgendwie möglich (nötig?!), steig auf das multiprocessing-modul um.

Re: Script terminiert nicht

Verfasst: Donnerstag 10. Februar 2011, 18:39
von BlackJack
Also ich finde ja auch das diese Funktionen die ``ps`` aufrufen komisch und sehr zerbrechlich aussehen.

Ein `wait()` auf die PIDs wäre sauberer und einfacher und wenn man schon mit der Prozessliste hantieren muss, würde ich das `psutil`-Modul installieren. Das ist robuster als die Ausgabe von ``ps`` zu verarbeiten und ausserdem plattformunabhängiger.

Re: Script terminiert nicht

Verfasst: Sonntag 13. Februar 2011, 22:42
von lill
Momentan ist es nicht meine Aufgabe, das Script zu optimieren.
Ich sollte es lediglich zum Laufen bringen. Mein Praktikum endet bald und ich werden mit weiteren Aufgaben überhäuft.
Trotzdem danke für die Tipps, ich werde diese weitergeben.