
Da das Problem von http://www.python-forum.de/viewtopic.php?p=23534#23534 ehr ein allgemeines mit execfile() ist, will ich es hier nochmal Schildern: test.py """ #!/usr/bin/python # -*- coding: UTF-8 -*- import test2 print "Content-type: text/html; charset=utf-8\r\n" print "test2.test:", test2.test """ test2.py """ #!/usr/bin/python # -*- coding: UTF-8 -*- test = "1" """ test3.py """ #!/usr/bin/python # -*- coding: UTF-8 -*- while 1: execfile( "test.py" ) raw_input( "weiter..." ) """ So, also man ruft test3.py auf... Es wird test.py ausgeführt, welches die Variable aus test2.py anzeigt. Soweit so gut. Nun gehen wir hin und ändern die Variable in test2.py auf einen anderen Wert (während die while-Schleife noch läuft!)... Drücken dann ENTER und sehen, das sie anscheinend noch nicht geändert wurde! Als ersten Work-a-Round, ich nutzte kein execfile() sondern führe per subprocess den Python-Interpreter aus: test3.py """ #!/usr/bin/python # -*- coding: UTF-8 -*- import sys, subprocess while 1: process = subprocess.Popen( "%s %s" % ( sys.executable, "test.py" ), cwd = ".", shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT ) while 1: line = process.stdout.readline() if line == "": break print line raw_input( "weiter..." ) """ Etwas aufwendig, aber es geht... Doch wie geht's einfacher? -- Mfg. Jens Diemer ---- http://www.jensdiemer.de _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Etwas aufwendig, aber es geht... Doch wie geht's einfacher?
Eventuell mit reload. Aber generell nur mit dem subprocess, zu den Gruenden siehe die Doku zu reload. Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
Eventuell mit reload. Aber generell nur mit dem subprocess, zu den Gruenden siehe die Doku zu reload.
Ja ich sehe auch nur eine Lösung mit subprocess. Im konkreten Fall geht's eigentlich um CGI's mit Python's eigenen CGI-Server. Der verwendet execfile() :( Ich möchte allerdings auch meine CGI-Skripte nicht extra anpassen und überall eine reload() machen... Meine aktuelle Lösung ist es, CGIHTTPServer.execfile zu überschreiben mit: """ class execscript: def __call__( self, scriptfile, dummy ): p = subprocess.Popen( "%s %s" % ( sys.executable, scriptfile ), cwd = ".", shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE ) p.stdin = sys.stdin sys.stdout.write( p.stdout.read() ) sys.stderr.write( p.stderr.read() ) CGIHTTPServer.execfile = execscript() """ Das klappt soweit. Änderungen sind immer wirksam, weil halt immer ein neuer Python-Interpreter gestartet wird. Nun hab ich allerdings ein neues Problem :( Und zwar, werden anscheinend keine POST-Formulare korrekt an's CGI geschickt. Genauer gesagt, liefert cgi.FieldStorage() keine Werte. Aus den cgi.py Sourcen kann man entnehmen, das cgi.FieldStorage() die Daten per stdin liest (Zeile 629). In CGIHTTPServer.py Zeile 294 wird anscheinen stdin irgendwie gefüttert. Offensichtlich klappt die übertragung der Daten per subprocess nicht richtig mit "p.stdin = sys.stdin" Ich weiß allerdings nicht wie es richtig gehen könnte :( -- Mfg. Jens Diemer ---- http://www.jensdiemer.de _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Offensichtlich klappt die übertragung der Daten per subprocess nicht richtig mit "p.stdin = sys.stdin"
Wie auch? Du willt ja Daten hin und her schaufeln, nicht ein Objekt unter nem anderen Namen binden (wie du das tust). Das hier sollte eher klappen: p.stdin.write(sys.stdin.read()) MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
Das hier sollte eher klappen: p.stdin.write(sys.stdin.read())
Leider nicht, es blockiert die Ausführung, weil wohl darauf gewartet wird, das über sys.stdin was rein kommt... -- Mfg. Jens Diemer ---- http://www.jensdiemer.de _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Am Mittwoch, 14. September 2005 17:14 schrieb jens diemer:
Diez B. Roggisch schrieb:
Das hier sollte eher klappen: p.stdin.write(sys.stdin.read())
Leider nicht, es blockiert die Ausführung, weil wohl darauf gewartet wird, das über sys.stdin was rein kommt...
Naja, sollte ja auch - das post-request, das wird ja dem eigentlichen CGI per stdin uebergeben. Eventuell ist das aber auch schon eingelesen, und du must dann halt die Variable in der das Request steht reinschreiben. Dann auch nicht p.stdin.close() vergessen (was ich schon getan habe...), denn sonst wartet der child-prozess. Ehrlich gesagt habe ich das Gefuehl das du dich da verrennst. Warum denn dieser reload/exec Quasch? Wir reden hier ueber CGI-Skripte, nicht nen j2ee-Appserver der >5min zum neustart braucht. Also einfach Ctrl-C, und neu starten. Kostet 5s, und funzt. Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
Ehrlich gesagt habe ich das Gefuehl das du dich da verrennst. Warum denn dieser reload/exec Quasch? Wir reden hier ueber CGI-Skripte, nicht nen j2ee-Appserver der >5min zum neustart braucht. Also einfach Ctrl-C, und neu starten. Kostet 5s, und funzt.
Da hast du eigentlich recht, aber es ist als "Entwicklungsumgebung" für PyLucid ( http://www.pylucid.org ) gedacht. Genauer gesagt ist es für die Standalone-Version gedacht: http://www.pylucid.org/index.py?p=/Doku/PyLucid%20Standalone Dabei werkelt man nicht an der Hauptdatei (index.py) sondern an irgendwelchen zusätzlichen Modulen... Das ist recht nervig, wenn man immer wieder den Server neustarten muß, wenn man was geändert hat. Vor allem, wenn man an den Neustart nicht gedacht hat, kommt es zu scheinbar merkwürdigen Effekten :( Ganz nebenbei würde man die Funktionalität vom CGIServer stark erweitern, wenn subprocess genommen wird, denn so erhält man theoretisch auch die Möglichkeit andere CGI-Skripte (außer Python) auszuführen. Was mich aber weniger interessiert ;) -- Mfg. Jens Diemer ---- http://www.jensdiemer.de _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Am Mittwoch, 14. September 2005 18:53 schrieb jens diemer:
Diez B. Roggisch schrieb:
Ehrlich gesagt habe ich das Gefuehl das du dich da verrennst. Warum denn dieser reload/exec Quasch? Wir reden hier ueber CGI-Skripte, nicht nen j2ee-Appserver der >5min zum neustart braucht. Also einfach Ctrl-C, und neu starten. Kostet 5s, und funzt.
Da hast du eigentlich recht, aber es ist als "Entwicklungsumgebung" für PyLucid ( http://www.pylucid.org ) gedacht. Genauer gesagt ist es für die Standalone-Version gedacht: http://www.pylucid.org/index.py?p=/Doku/PyLucid%20Standalone
Dabei werkelt man nicht an der Hauptdatei (index.py) sondern an irgendwelchen zusätzlichen Modulen...
Das ist recht nervig, wenn man immer wieder den Server neustarten muß, wenn man was geändert hat. Vor allem, wenn man an den Neustart nicht gedacht hat, kommt es zu scheinbar merkwürdigen Effekten :(
Ganz nebenbei würde man die Funktionalität vom CGIServer stark erweitern, wenn subprocess genommen wird, denn so erhält man theoretisch auch die Möglichkeit andere CGI-Skripte (außer Python) auszuführen. Was mich aber weniger interessiert ;)
Welches Betriebssystem verwendest Du? Das CGIHTTPServer-Modul von Python 2.4 verwendet execfile() nur im Notfall, wenn weder os.fork() noch os.popen2()/os.popen3() vorhanden sind. Damit sollten unter Linux und Windows beliebige CGI-Skripte laufen und Änderungen sofort sichtbar sein. Mac wird im Quelltext als Fall für execfile() genannt, aber ich vermute, dass die älteren nicht BSD-basierten Varianten gemeint sind. Peter PS: Habe unter Linux mit einem Perl-Skript erfolgreich getestet. _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Peter Otten schrieb:
Welches Betriebssystem verwendest Du? Das CGIHTTPServer-Modul von Python 2.4 verwendet execfile() nur im Notfall, wenn weder os.fork() noch os.popen2()/os.popen3() vorhanden sind.
Danke für den Hinweis. Das ist auch die Lösung für mein Problem: Und zwar ist es so, das ich den Server vorher in einem anderen Projekt benutzt hab. Da war es wichtig, das CGI-Skripte mit dem User ausgeführt werden, mit dem der Server gestartet ist. Das ist unter Linux nicht so, da Linux fork bzw. os.setuid() unterstützt. In dem Fall werden Skripte als User nobody ausgeführt. Das kann man in CGIHTTPServer.py in Zeile 204 bzw. 225 sehen. Deswegen hatte ich im RequestHandler meines Servers diese drei Zeilen drin: """ have_fork = False have_popen2 = False have_popen3 = False """ Das bedeutet aber auch, das die Skripte immer mit execfile() aufgeführt werden, was eigentlich nur eine Notlösung ist. Lange Rede kurzer Sinn... Durch das löschen der drei have_*-Zeilen, hat sich mein Problem in Luft aufgelöst. Sorry, war mein Fehler... -- Mfg. Jens Diemer ---- http://www.jensdiemer.de _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Am Donnerstag, 15. September 2005 09:25 schrieb jens diemer:
Welches Betriebssystem verwendest Du? Das CGIHTTPServer-Modul von Python 2.4 verwendet execfile() nur im Notfall, wenn weder os.fork() noch os.popen2()/os.popen3() vorhanden sind.
Danke für den Hinweis. Das ist auch die Lösung für mein Problem:
Und zwar ist es so, das ich den Server vorher in einem anderen Projekt benutzt hab. Da war es wichtig, das CGI-Skripte mit dem User ausgeführt werden, mit dem der Server gestartet ist.
Als kleine Anregung wie man das ohne bleibende Schäden lösen könnte (ungetestet): import CGIHTTPServer import os if __name__ == "__main__": CGIHTTPServer.nobody = os.getuid() CGIHTTPServer.test()
Deswegen hatte ich im RequestHandler meines Servers diese drei Zeilen drin: """ have_fork = False have_popen2 = False have_popen3 = False """
Ouch.
Sorry, war mein Fehler...
Naja, ich hoffe, es tut Dir mehr weh als uns :-) Peter _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de
participants (3)
-
Diez B. Roggisch
-
jens diemer
-
Peter Otten