Wie sende ich ein SIGINT von einem Bash-Skript an Python?

9

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.

    
Ryan 10.06.2009, 07:46
quelle

5 Antworten

15

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%     
Matthew Flaschen 10.06.2009, 08:00
quelle
4

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%     
Michiel Buddingh 10.06.2009 08:12
quelle
2

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%     
tomoe 10.06.2009 13:58
quelle
2

Zusätzlich zu @ matthew-flaschens Antwort können Sie exec im Bash-Skript verwenden, um den Bereich effektiv durch den Prozess zu ersetzen, der geöffnet wird:

%Vor%     
Steen 14.06.2017 07:56
quelle
1

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:

%Vor%     
Eric Cousineau 13.12.2017 20:51
quelle

Tags und Links