(Python) Programm lässt sich nicht mit Strg+C beenden
Julian von Mendel
- sonstiges
Hallo!
Ich hab vor kurzem angefangen mit PyQT und Threading unter Linux zu programmieren. Ich habe aber das Problem, dass mein Progamm sich nicht - wie ich es von anderen Programmen gewohnt bin - mit Strg+C beenden lässt. Ich hab vor ein paar Tagen einen Lösungsvorschlag irgendwo gelesen, finde ihn aber einfach nicht wieder. Ich hab die python.faqts, Google und ein anscheinend äußerst inaktives Python-Forum abgesucht... Kann mir jemand sagen, was ich machen muss, dass mein Programm sich wie jedes andere beenden lässt?
Danke
Julian
Hallo Julian
Ich habe aber das Problem, dass mein Progamm sich nicht - wie ich es von anderen Programmen gewohnt bin - mit Strg+C beenden lässt.
Schon mal
kill
probiert?
Freundliche Grüße
Vinzenz
Hi,
Schon mal
kill
probiert?
öh, du verstehst mich falsch. Ich habe kein Problem damit das Programm "brutal" zu beenden. Aber ich möchte, dass es eben ganz normal, wie andere Programme, auf Strg+C reagiert. kill ist unpraktisch und unnormal.
Schöne Grüße
Julian
Hi Julian!
Ich hab vor kurzem angefangen mit PyQT und Threading unter Linux zu programmieren. Ich habe aber das Problem, dass mein Progamm sich nicht - wie ich es von anderen Programmen gewohnt bin - mit Strg+C beenden lässt. Ich hab vor ein paar Tagen einen Lösungsvorschlag irgendwo gelesen, finde ihn aber einfach nicht wieder. Ich hab die python.faqts, Google und ein anscheinend äußerst inaktives Python-Forum abgesucht... Kann mir jemand sagen, was ich machen muss, dass mein Programm sich wie jedes andere beenden lässt?
Was passiert denn, wenn du Ctrl + C drückst? Normalerweise sollte da eine Exception (KeyboardInterrupt) ausgelöst werden, die du entsprechend abfangen kannst. Folgendes Beispiel funktioniert, wie es soll:
#!/usr/bin/python2.4
import sys
while True:
try:
answer = raw_input('Bitte Antwort eingeben:\n')
if answer != 'JA':
continue
else:
print 'Du hast "Ja" eingegeben!\n'
break
except KeyboardInterrupt:
print 'Beenden'
sys.exit(1)
Grüße,
Fabian St.
Hi,
es passier exakt garnichts. Ich habe dein try-except-Konstrukt jetzt mal um meinen Hauptprogrammteil rumgebaut, so:
try:
app = QApplication(sys.argv)
app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()'))
form = simulation()
form.show()
app.setMainWidget(form)
app.exec_loop()
except KeyboardInterrupt:
print 'Beenden'
sys.exit(1)
Das hat jedoch nichts geändert.
Schöne Grüße
Julian
Hi Julian!
es passier exakt garnichts. Ich habe dein try-except-Konstrukt jetzt mal um meinen Hauptprogrammteil rumgebaut, so:
try:
app = QApplication(sys.argv)
app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()'))
form = simulation()
form.show()
app.setMainWidget(form)
app.exec_loop()
except KeyboardInterrupt:
print 'Beenden'
sys.exit(1)
Sorry, ich habe überlesen, dass es sich um eine GUI-Anwendung mit PyQT handelt. Da kann ich dir leider nicht weiterhelfen. Eventuell gibt es für PyQT jedoch irgendeine eine Event-Listener-Methode, mit der du ein Drücken von Crtl + C abfangen könntest, um dementsprechend darauf reagieren zu können.
Grüße,
Fabian St.
--
Selfcode: [ie:{ fl:( br:> va:) ls:\[ fo:) rl:( n4:( ss:) de:> js:| ch:? mo:) zu:)](http://www.peter.in-berlin.de/projekte/selfcode/?code=ie%3A%7B+fl%3A%28+br%3A%3E+va%3A%29+ls%3A%5B+fo%3A%29+rl%3A%28+n4%3A%28+ss%3A%29+de%3A%3E+js%3A%7C+ch%3A%3F+mo%3A%29+zu%3A%29)
Hallo Fabian,
Sorry, ich habe überlesen, dass es sich um eine GUI-Anwendung mit PyQT handelt. Da kann ich dir leider nicht weiterhelfen. Eventuell gibt es für PyQT jedoch irgendeine eine Event-Listener-Methode, mit der du ein Drücken von Crtl + C abfangen könntest, um dementsprechend darauf reagieren zu können.
trotzdem danke :)
Ich lern grad Python und hab noch vieeeel mehr Probleme. Kennst du ein gutes Forum/Board, das ein wenig aktiver ist als http://python.sandtner.net/? Sonst muss ich immer im SelfForum nerven ;)
Schöne Grüße
Julian
Hallo,
Ich lern grad Python und hab noch vieeeel mehr Probleme. Kennst du ein gutes Forum/Board, das ein wenig aktiver ist als http://python.sandtner.net/? Sonst muss ich immer im SelfForum nerven ;)
Du kannst es auf den Newsgroups/Mailinglisten versuchen, die sind sehr gut besucht:
http://www.python.org/community/lists.html
Zu deinem Problem:
Also du hast ein GUI-Programm geschrieben, dass du von der Konsole startest und nicht per Strg+C auf der Konsole beenden kannst? Bist du dir sicher, dass dein Window Manager den Focus auf dem xterm und nicht etwa auf dem Programm hat?
Gruß,
Severin
Hi Julian!
Sorry, ich habe überlesen, dass es sich um eine GUI-Anwendung mit PyQT handelt. Da kann ich dir leider nicht weiterhelfen. Eventuell gibt es für PyQT jedoch irgendeine eine Event-Listener-Methode, mit der du ein Drücken von Crtl + C abfangen könntest, um dementsprechend darauf reagieren zu können.
trotzdem danke :)
Ich lern grad Python und hab noch vieeeel mehr Probleme. Kennst du ein gutes Forum/Board, das ein wenig aktiver ist als http://python.sandtner.net/? Sonst muss ich immer im SelfForum nerven ;)
Ich bin auch gerade dabei, mich mit Python ein bisschen näher auseinander zu setzen - PHP wird auf die Dauer langweilig und man will ja auch mal seinen Horizont erweitern ;-) Bzgl. deiner Frage nach einem Python-Forum kann ich leider nichts sagen, weil ich bisher noch keine Probleme hatte, die nicht mittels der offiziellen Referenz oder den zahlreichen Ebooks geklärt werden hätten können.
Ich hätte da jetzt noch was bzgl. deines Problems gefunden:
Füge mal die Zeile signal.signal(signal.SIGINT, signal.SIG_DFL)
hinzu, bevor du app.exec_loop() aufrufst. Davor musst du jedoch noch das Modul signal importieren. SIGINT ist dabei das Interrupt-Signal, das an das Programm gesendet wird, wenn Crtl + C gedrückt wird. Anstatt signal.SIG_DFL kann auch eine eigene Handlerfunktion übergeben werden. Siehe hierzu auch http://docs.python.org/lib/module-signal.html.
Auf diese Idee bin ich durch diesen Google-Treffer gekommen.
Grüße,
Fabian St.
Hi,
Ich hätte da jetzt noch was bzgl. deines Problems gefunden:
Füge mal die Zeilesignal.signal(signal.SIGINT, signal.SIG_DFL)
hinzu, bevor du app.exec_loop() aufrufst. Davor musst du jedoch noch das Modul signal importieren. SIGINT ist dabei das Interrupt-Signal, das an das Programm gesendet wird, wenn Crtl + C gedrückt wird.
Es ist häufiger SIGTERM bei STRG+C, Kostet aber auch nix, beide zu überwachen.
so short
Christoph Zurnieden
Hi Christoph!
Ich hätte da jetzt noch was bzgl. deines Problems gefunden:
Füge mal die Zeilesignal.signal(signal.SIGINT, signal.SIG_DFL)
hinzu, bevor du app.exec_loop() aufrufst. Davor musst du jedoch noch das Modul signal importieren. SIGINT ist dabei das Interrupt-Signal, das an das Programm gesendet wird, wenn Crtl + C gedrückt wird.Es ist häufiger SIGTERM bei STRG+C, Kostet aber auch nix, beide zu überwachen.
So? Ich habe mich daran gehalten: http://www.wlug.org.nz/SIGINT.
Grüße,
Fabian St.
Hi,
Es ist häufiger SIGTERM bei STRG+C, Kostet aber auch nix, beide zu überwachen.
Ja, ich gebe offen zu: das "häufiger" war eine offene Provokation ;-)
So? Ich habe mich daran gehalten: http://www.wlug.org.nz/SIGINT.
Ist kein internationales Standardorgan, interessiert also nicht die Bohne.
Aber ich erkläre mich auch gerne genauer: nicht nur, das es nur "meistens" SIGINT ist und auch nur "meistens" das Programm beendet so heißt das noch lange nichts. Das zur regulären Programmbeendung vorgesehene Signal ist nunmal SIGTERM.
so short
Christoph Zurnieden
PS: Zum probieren (autogeneriert aus der LIBC-Infodatei, blöderweise ist beim Ausprobieren mit STRG+D die History des kterms verlorengegangen, deshalb hier nur der generierte und daher recht längliche und sehr ungeschickt aussehende Code)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void sigprocint(){
puts("SIGINT sent.");
}
void sigprocfpe(){
puts("SIGFPE sent.");
}
void sigprocill(){
puts("SIGILL sent.");
}
void sigprocsegv(){
puts("SIGSEGV sent. How did you got this message?");
}
void sigprocbus(){
puts("SIGBUS sent.");
}
void sigproctrap(){
puts("SIGTRAP sent. What debugger are you using?");
}
void sigprociot(){
puts("SIGIOT sent. Oh, we're running on a PDP-11?");
}
void sigprocabrt(){
puts("SIGABRT sent.");
}
void sigprocemt(){
puts("SIGEMT sent. Not really, only emulated.");
}
void sigprocsys(){
puts("SIGSYS sent.");
}
void sigprocterm(){
puts("SIGTERM sent.");
}
void sigprocquit(){
puts("SIGQUIT sent.");
}
void sigprockill(){
puts("SIGKILL sent. How did you get _that_?");
}
void sigprochup(){
puts("SIGHUP sent.");
}
void sigprocalrm(){
puts("SIGALARM sent.");
}
void sigprocvtalrm(){
puts("SIGVTALRM sent.");
}
void sigprocprof(){
puts("SIGPROF sent.");
}
void sigprocio(){
puts("SIGIO sent.");
}
void sigprocurg(){
puts("SIGURG sent.");
}
void sigprocpoll(){
puts("SIGPOLL sent. SCO's greeting, they want their code back!");
}
void sigprocchld(){
puts("SIGCHLD sent.");
}
void sigproccld(){
puts("SIGCLD sent. Quit ol' system, hu?");
}
void sigproccont(){
puts("SIGCONT sent.");
}
void sigprocstop(){
puts("SIGSTOP sent. Hu?");
}
void sigprocstp(){
puts("SIGSTP sent.");
}
void sigprocttin(){
puts("SIGTTIN sent.");
}
void sigprocttou(){
puts("SIGTTOU sent.");
}
void sigprocpipe(){
puts("SIGTPIPE sent.");
}
void sigproclost(){
puts("SIGTLOST sent.");
}
void sigprocxcpu(){
puts("SIGTXCPU sent. Please resist nethack");
}
void sigprocxfsz(){
puts("SIGTXFSZ sent. To much pr0n on device.");
}
void sigprocusr1(){
puts("SIGTUSR1 sent.");
}
void sigprocusr2(){
puts("SIGTUSR2 sent.");
}
void sigprocwinch(){
puts("SIGTWINCH sent.");
}
void sigprocinfo(){
puts("SIGTINFO sent.");
}
int main(){
signal(SIGINT,sigprocint);
signal(SIGFPE,sigprocfpe);
signal(SIGILL,sigprocill);
signal(SIGSEGV,sigprocsegv);
signal(SIGBUS,sigprocbus);
signal(SIGTRAP,sigproctrap);
signal(SIGIOT,sigprociot);
signal(SIGABRT,sigprocabrt);
#ifdef SIGEMT
signal(SIGEMT,sigprocemt);
#endif
signal(SIGSYS,sigprocsys);
signal(SIGSYS,sigprocsys);
signal(SIGTERM,sigprocterm);
signal(SIGINT,sigprocint);
signal(SIGQUIT,sigprocquit);
signal(SIGKILL,sigprockill);
signal(SIGHUP,sigprochup);
signal(SIGALRM,sigprocalrm);
signal(SIGVTALRM,sigprocvtalrm);
signal(SIGPROF,sigprocprof);
signal(SIGIO,sigprocio);
signal(SIGURG,sigprocurg);
signal(SIGPOLL,sigprocpoll);
signal(SIGCHLD,sigprocchld);
signal(SIGCLD,sigproccld);
signal(SIGCONT,sigproccont);
signal(SIGSTOP,sigprocstop);
#ifdef SIGSTP
signal(SIGSTP,sigprocstp);
#endif
signal(SIGTTIN,sigprocttin);
signal(SIGTTIN,sigprocttin);
signal(SIGTTOU,sigprocttou);
signal(SIGPIPE,sigprocpipe);
#ifdef SIGLOST
signal(SIGLOST,sigproclost);
#endif
signal(SIGXCPU,sigprocxcpu);
signal(SIGXFSZ,sigprocxfsz);
signal(SIGUSR1,sigprocusr1);
signal(SIGUSR2,sigprocusr2);
signal(SIGWINCH,sigprocwinch);
#ifdef SIGINFO
signal(SIGINFO,sigprocinfo);
#endif
printf("Send SIGKILL to PID %d to end this program,\
any other signal might be caught and printed.\n\n", getpid());
for(;;)
pause();
exit(EXIT_SUCCESS);
}
CZ
Hallo.
Ist kein internationales Standardorgan
Das einzige internationale Standardorgan ist doch das, welches man in Angelegenheit steckt, die einen nichts angehen.
MfG, at
Hi,
Ist kein internationales Standardorgan
Das einzige internationale Standardorgan ist doch das, welches man in Angelegenheit steckt, die einen nichts angehen.
Nein, das wäre dann das Standartorgan.
so short
Christoph Zurnieden
Hallo.
Das einzige internationale Standardorgan ist doch das, welches man in Angelegenheit steckt, die einen nichts angehen.
Nein, das wäre dann das Standartorgan.
"Die Nase im Wind"
MfG, at
Hi Christoph!
Es ist häufiger SIGTERM bei STRG+C, Kostet aber auch nix, beide zu überwachen.
Ja, ich gebe offen zu: das "häufiger" war eine offene Provokation ;-)
Inwieweit häufiger? D.h. wann ist ein Crtl+C ein SIGINT, wann ein SIGTERM?
So? Ich habe mich daran gehalten: http://www.wlug.org.nz/SIGINT.
Ist kein internationales Standardorgan, interessiert also nicht die Bohne.
Aber ich erkläre mich auch gerne genauer: nicht nur, das es nur "meistens" SIGINT ist und auch nur "meistens" das Programm beendet so heißt das noch lange nichts. Das zur regulären Programmbeendung vorgesehene Signal ist nunmal SIGTERM.
OK, dann hast du meine obige Frage hiermit beantwortet ;-) Danke.
PS: Zum probieren (autogeneriert aus der LIBC-Infodatei, blöderweise ist beim Ausprobieren mit STRG+D die History des kterms verlorengegangen, deshalb hier nur der generierte und daher recht längliche und sehr ungeschickt aussehende Code)
[C-Programmm]
Ergibt bei mir nach dem Kompilieren mit dem gcc folgende Ausgabe:
fabi@jupiter ~/tmp [ 20:22:22 ] $ ./test
Send SIGKILL to PID 18789 to end this program, any other signal might be caught and printed.
SIGINT sent.
Hier wurde Crtl+C gedrückt. Für diesen Fall stimmt also meine Aussage ;-)
Grüße,
Fabian St.
Hi,
Inwieweit häufiger? D.h. wann ist ein Crtl+C ein SIGINT, wann ein SIGTERM?
Es ist z.B. dann SIGTERM, wenn ich die Kiste eingerichtet habe ;-)
Ergibt bei mir nach dem Kompilieren mit dem gcc
Das sollte auch mit allen anderen standardkonformen C-Compilern und einem POSIX-konformem OS funktionieren. Aber außer pause() (kann auch einfach durch ein Konstrukt mit sleep() ersetzt werden) und getpid() (Da ist die Alternative OS-abhängig) ist alles ANSI-C.
fabi@jupiter ~/tmp [ 20:22:22 ] $ ./test
Send SIGKILL to PID 18789 to end this program, any other signal might be caught and printed.SIGINT sent.
Hier wurde Crtl+C gedrückt.
Watt denn, datt Dingen funktioniert wirklich? ;-)
Für diesen Fall stimmt also meine Aussage ;-)
Du bist also nicht bei einer Firma beschäftigt deren Kisten ich eingerichtet habe? >;->
(Bevor jemand fragt: nein, Windows bearbeite ich nicht dahingehend, ich möchte mir die mageren Reste meiner geistigen Gesundheit noch erhalten.)
so short
Christoph Zurnieden
你好 Christoph,
Ich hätte da jetzt noch was bzgl. deines Problems gefunden:
Füge mal die Zeile ~~~python
signal.signal(signal.SIGINT,
signal.SIG_DFL)
> > musst du jedoch noch das Modul signal importieren. SIGINT ist dabei das
> > Interrupt-Signal, das an das Programm gesendet wird, wenn Crtl + C
> > gedrückt wird.
>
> Es ist häufiger SIGTERM bei STRG+C, Kostet aber auch nix, beide zu
> überwachen.
\*hüstel\* Häufiger ist übertrieben. Ich kenne genau genommen keine andere
Standard-Regelung (sic! Natürlich kann man alles umbauen, aber dann ist es
nicht mehr Standard ;-) als bei Strg+C SIGINT zu senden ;) Und ich kenne
durchaus einige Unix-artige Systeme ;-)
再见,
克里斯蒂安
--
Der Mund ist das Portal zum Unglück.
<http://wwwtech.de/>
Hi,
*hüstel*
Ich habe schon an anderer Stelle einmal Salbeitee gegen diese spezielle Art von Halsreizungen empfohlen und tue es gerne wieder ;-)
Häufiger ist übertrieben. Ich kenne genau genommen keine andere
Standard-Regelung (sic! Natürlich kann man alles umbauen, aber dann ist es
nicht mehr Standard ;-)
Problem: es ist kein Standrad.
als bei Strg+C SIGINT zu senden ;) Und ich kenne
durchaus einige Unix-artige Systeme ;-)
Das mit dem C-c für SIGINT liegt nicht am System, sondern an der Shell/Editor/wwi.
Wenn Du einem anständig eingerichtetem System beim Runterfahren zuschaust wirst Du sehen, das alle noch laufenden Prozesse erst ein SIGTERM und dann, nach einer kleinen Höflichkeitspause, ein SIGKILL. Ein SIGINT habe ich zwar auch schon hin und wieder aufgefunden, war aber auch immer (ja, immer! Bis jetzt keine Ausnahmen gefunden!) ein Zeichen, das noch mehr "nicht so ganz in Ordnung" war und in der Summe um ein erneutes Aufsetzen meist nicht drumherumzukommen war.
Gut, da ich mit solchen und ähnlichen Dingen meine Butter auf's Brot verdiene sehe ich das naturgemäß etwas enger, aber trotzdem! ;-)
Aber ich schweife ab.
Mein Problem mit C-c ist nicht, das es ein SIGINT triggert, sondern das ein Programm statt ordnungsgemäß und vor allem standardkonform (POSIX) ein SIGTERM als Hinweis darauf zu bekommen sich zu beenden recht brutal mit SIGINT unterbrochen wird. Deshalb auch mein Sarkasmus, das es doch nix kosten würde einfach beide Signale zu überwachen.
so short
Christoph Zurnieden
你好 Christoph,
*hüstel*
Ich habe schon an anderer Stelle einmal Salbeitee gegen diese spezielle
Art von Halsreizungen empfohlen und tue es gerne wieder ;-)
Danke, nicht nötig, das gibt sich von selbst wieder ;)
Häufiger ist übertrieben. Ich kenne genau genommen keine andere
Standard-Regelung (sic! Natürlich kann man alles umbauen, aber dann ist
es nicht mehr Standard ;-)Problem: es ist kein Standrad.
Kommt drauf an, wie du das Wörtchen Standard definierst ;) Es ist in dem
Sinne ein Standard, dass es bei vielen Systemen per Default so ist; auf diesen Systemen kann man das getrost „Standard“ nennen ;)
als bei Strg+C SIGINT zu senden ;) Und ich kenne
durchaus einige Unix-artige Systeme ;-)Das mit dem C-c für SIGINT liegt nicht am System, sondern an der
Shell/Editor/wwi.
Ja, das stimmt — habe ja auch nichts anderes behauptet.
Wenn Du einem anständig eingerichtetem System beim Runterfahren zuschaust
wirst Du sehen, das alle noch laufenden Prozesse erst ein SIGTERM und
dann, nach einer kleinen Höflichkeitspause, ein SIGKILL. Ein SIGINT habe
ich zwar auch schon hin und wieder aufgefunden, war aber auch immer (ja,
immer! Bis jetzt keine Ausnahmen gefunden!) ein Zeichen, das noch mehr
"nicht so ganz in Ordnung" war und in der Summe um ein erneutes Aufsetzen
meist nicht drumherumzukommen war.
Du schweifst vom Thema ab :) Das hat nun nichts mehr damit zu tun.
Gut, da ich mit solchen und ähnlichen Dingen meine Butter auf's Brot
verdiene sehe ich das naturgemäß etwas enger, aber trotzdem! ;-)
Aber ich schweife ab.
Sag ich ja *g*
Mein Problem mit C-c ist nicht, das es ein SIGINT triggert, sondern das
ein Programm statt ordnungsgemäß und vor allem standardkonform (POSIX)
ein SIGTERM als Hinweis darauf zu bekommen sich zu beenden recht brutal
mit SIGINT unterbrochen wird. Deshalb auch mein Sarkasmus, das es doch
nix kosten würde einfach beide Signale zu überwachen.
Natürlich sollte man beide Signale überwachen. In dem Punkt habe ich dir ja
gar nicht widersprochen – es gibt schliesslich immer wieder Leute wie
dich >;)))
So, jetzt ist aber Schluss, das nächste mal erst wieder in 1,5 Wochen *g*
再见,
克里斯蒂安
Hi,
So, jetzt ist aber Schluss, das nächste mal erst wieder in 1,5 Wochen *g*
Ach, mich packt der Neid, der giftig-gelbe *sigh*
viel Spaß wünscht
Christoph Zurnieden
Hi Fabian,
Ich bin auch gerade dabei, mich mit Python ein bisschen näher auseinander zu setzen - PHP wird auf die Dauer langweilig und man will ja auch mal seinen Horizont erweitern ;-)
ich lerne Python weil PHP keine Qt-Bindings hat, soweit ich weiß ;) Aber es hat wirklich einige interessante Funktionen und praktische Module. Kann man mit PHP eigentlich auch Operatoren überladen? (Wieso gibts keine PHP-Qt-Bindings? Wäre das so aufwendig?)
Schöne Grüße
Julian
Wenn man das QT-Fenster schließt beendet das Programm aber schon! D. h. es geht nur aus der Konsole heraus nicht.
Schöne Grüße
Julian
你好 Julian,
bin kein Python-Experte, aber vermutlich reicht es, wenn du das Modul „signal“
importierst und mit der Funktion „signal()“ deinen Signal-Handler für SIGINT
setzt. Deine Problembeschreibung hört sich an, als würde ein Teil der
GUI-Bibliothek SIGINT abfangen und ignorieren ⇒ den Signal-Handler
überschreiben mit einem eigenen.
再见,
克里斯蒂安
Hi Christian,
vielen Dank. Jetzt gehts!
Auch danke an die anderen :)
Schöne Grüße
Julian