Ich möchte einen Hintergrund-Python-Job von einem Bash-Skript starten und ihn anschließend mit SIGINT ordnungsgemäß beenden. Das funktioniert gut von der Shell, aber ich kann nicht scheinen, es in einem Skript zu arbeiten.
loop.py:
%Vor%Von der Shell kann ich es unterbrechen:
%Vor%kill.sh:
%Vor%Aber aus einem Skript kann ich nicht:
%Vor%Und wenn es von einem Skript gestartet wurde, kann ich es nicht mehr aus der Shell löschen:
%Vor%Ich gehe davon aus, dass mir ein feiner Punkt der bash job control fehlt.
Sie registrieren keinen Signal-Handler. Probieren Sie das unten. Es scheint ziemlich zuverlässig zu funktionieren. Ich denke, die seltene Ausnahme ist, wenn es das Signal abfängt, bevor Python den Handler des Skripts registriert. Beachten Sie, dass KeyboardInterrupt nur ausgelöst werden soll, "wenn der Benutzer die Interrupt-Taste drückt". Ich denke, die Tatsache, dass es für ein explizites (z. B. via kill) SIGINT überhaupt funktioniert, ist ein Zufall der Implementierung.
%Vor%Ich stimme Matthew Flaschen zu; Das Problem ist mit Python, das die Ausnahme KeyboardInterrupt anscheinend nicht mit SIGINT registriert, wenn es nicht von einer interaktiven Shell aufgerufen wird.
Natürlich verhindert nichts, dass Sie Ihren Signalhandler wie folgt registrieren:
%Vor%Wenn Sie den Befehl im Hintergrund mit & amp; ausführen, wird SIGINT ignoriert. Hier ist der relevante Abschnitt von man bash:
Nicht integrierte Befehle, die von bash ausgeführt werden, haben Signalbehandlungsroutinen, die auf die von der Shell vererbten Werte gesetzt sind sein Elternteil. Wenn die Jobsteuerung nicht aktiv ist, ignorieren asynchrone Befehle SIGINT und SIGQUIT in Zusätzlich zu diesen ererbten Handler. Befehle, die als Ergebnis einer Befehlsersetzung ausgeführt werden, ignorieren den Befehl Tastatur-generierte Auftragskontrollsignale SIGTTIN, SIGTTOU und SIGTSTP.
Ich denke, Sie müssen den Signal-Handler explizit einstellen, wie Matthew kommentierte.
Das Skript kill.sh hat ebenfalls ein Problem. Da loop.py an den Hintergrund gesendet wird, gibt es keine Garantie dafür, dass kill nach python loop.py ausgeführt wird.
%Vor%Versuchte @ Steen Ansatz, aber ach, es hält offenbar nicht auf Mac.
Eine andere Lösung, ähnlich wie oben, aber etwas allgemeiner, besteht darin, den Standardhandler einfach neu zu installieren, wenn SIGINT
ignoriert wird: