Wenn Sie nicht versuchen, ein solches Ereignis zu warten, aber in einer parallelen Sitzung senden SIGTERM
zu diesem Prozess (zB durch kill -15 $PID
auf der Prozess-ID $PID
des Python-Skript läuft Aufruf), sollten Sie einen lehrreichen Fehlermeldung angezeigt; -)
Auch der Kommentar über den Mount-Punkt sollte von Interesse sein, nachdem Sie die Python-Fehler (TypeError: cannot concatenate 'str' and 'int' objects
) repariert haben.
Probieren Sie etwas wie:
import time
import signal
import sys
LOG_PATH = '/mnt/usbdrive/output/TestSignal.txt'
def CloseAll(Code, Frame):
f = open(LOG_PATH, 'a')
f.write('Signal Code:' + str(Code) + ' ')
f.write('Signal Frame:' + str(Frame))
f.write('\r\n')
f.close()
sys.exit(0)
signal.signal(signal.SIGTERM, CloseAll)
print('Program is running')
try:
while True:
# get readings from sensors every 15 seconds
time.sleep(15)
f = open(LOG_PATH, 'a')
f.write('Hello ')
f.write('\r\n')
f.close()
except KeyboardInterrupt:
f = open(LOG_PATH, 'a')
f.write('Done')
f.write('\r\n')
f.close()
als Ausgangspunkt. Wenn dies irgendwie auf Ihrem System funktioniert, warum nicht einige Teile neu zu schreiben wie:
# ... 8< - - -
def close_all(signum, frame):
with open(LOG_PATH, 'a') as f:
f.write('Signal Code:%d Signal Frame:%s\r\n' % (signum, frame))
sys.exit(0)
signal.signal(signal.SIGTERM, close_all)
# 8< - - - ...
bearbeiten: Um den Fehler zu isolieren und mehr anpassen wie Modus Produktion, könnte man den Code wie folgt neu schreiben (vorausgesetzt, dass syslog ist auf der Maschine laufen, die es sein sollte, aber ich auf Geräten dieser Art noch nie gearbeitet):
#! /usr/bin/env python
import datetime as dt
import time
import signal
import sys
import syslog
LOG_PATH = 'foobarbaz.log' # '/mnt/usbdrive/output/TestSignal.txt'
def close_all(signum, frame):
"""Log to system log. Do not spend too much time after receipt of TERM."""
syslog.syslog(syslog.LOG_CRIT, 'Signal Number:%d {%s}' % (signum, frame))
sys.exit(0)
# register handler for SIGTERM(15) signal
signal.signal(signal.SIGTERM, close_all)
def get_sensor_readings_every(seconds):
"""Mock for sensor readings every seconds seconds."""
time.sleep(seconds)
return dt.datetime.now()
def main():
"""Main loop - maybe check usage patterns for file resources."""
syslog.syslog(syslog.LOG_USER, 'Program %s is running' % (__file__,))
try:
with open(LOG_PATH, 'a') as f:
while True:
f.write('Hello at %s\r\n' % (
get_sensor_readings_every(15),))
except KeyboardInterrupt:
with open(LOG_PATH, 'a') as f:
f.write('Done at %s\r\n' % (dt.datetime.now(),))
if __name__ == '__main__':
sys.exit(main())
Punkte zu beachten:
- die Protokolldatei für die tatsächlichen Messungen ist getrennt von dem Protokollierungs Kanal für Betriebs Warnungen
- die Protokolldatei Griff in Zusammenhang Verwalten Blöcken und in üblichen Betrieb gesichert wird, wird nur offen gehalten
- zum Alarmieren des
syslog
Kanal verwendet wird.
- als Beispiel für die Nachrichtenrouting die
syslog.LOG_USER
auf meinem System (OS X) gibt mir in allen Terminals eine Nachricht, während die syslog.LOG_ERR
Priorität Nachricht im Signal-Handler zielt nur auf das Systemprotokoll.
- sollte mehr auf den Punkt während des Herunterfahrens stress (nicht das Öffnen einer Datei usw.)
)
Der letzte Punkt (5) für den Fall wichtig ist, alle Prozesse erhalten ein SIGTERM
während des Abschaltens, dh alle etwas tun wollen (Dinge nach unten) zu verlangsamen, vielleicht screen
auch nimmt keinen gepufferten Eingang mehr (oder nicht bündig), notieren Sie stdout
ist Block gepuffert nicht Zeile gepuffert.
Die Entkopplung der Ausgangskanäle sollte auch das Verschwinden des Mountpunkts der Messprotokolldatei erleichtern.
Sind Sie sicher, dass das Medium noch eingehängt ist, wenn der Handler ausgeführt wird? –
@RDK Bitte überprüfen Sie meine Antwort (es funktioniert auf meinem System), aber versuchen Sie auch in der 'CloseAll' Funktion Körper ziemlich atomaren und haben ein Auge auf die Verfügbarkeit der Mount-Punkt während des Herunterfahrens als http://stackoverflow.com/ Benutzer/20862/Ignacio-Vazquez-Abrams oben angegeben. – Dilettant