2016-01-20 3 views
3

Я написал простую программу python и запустил ее как службу systemd. Я хотел бы что-то сделать (например, написать сообщение в файл журнала), прежде чем systemd закроет эту запущенную программу python.Сделайте что-нибудь, прежде чем systemd прекратит работу службы python

Я попытался atexit (как упоминалось в этом посте: Doing something before program exit), я также попытался поймать SIGTERM (как описано здесь: https://nattster.wordpress.com/2013/06/05/catch-kill-signal-in-python/), но без успеха.

Я использую raspbian-jessie и python2.7.

Как я могу что-то сделать до того, как systemd убивает запущенную программу python?

Ниже приведен пример фрагмента кода (с atexit):

#!/usr/bin/env python 

from pymodbus.server.async import StartTcpServer 

from pymodbus.device import ModbusDeviceIdentification 
from pymodbus.datastore import ModbusSequentialDataBlock 
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext 

import atexit 

import logging 
logging.basicConfig() 
log = logging.getLogger() 
log.setLevel(logging.DEBUG) 

def exit_handler(): 
    log.warning('My application is ending!') 

atexit.register(exit_handler) 

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [17]*100), 
    co = ModbusSequentialDataBlock(0, [17]*100), 
    hr = ModbusSequentialDataBlock(0, [17]*100), 
    ir = ModbusSequentialDataBlock(0, [17]*100)) 
context = ModbusServerContext(slaves=store, single=True) 

identity = ModbusDeviceIdentification() 
identity.VendorName = 'Pymodbus' 
identity.ProductCode = 'PM' 
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' 
identity.ProductName = 'Pymodbus Server' 
identity.ModelName = 'Pymodbus Server' 
identity.MajorMinorRevision = '1.0' 

StartTcpServer(context, identity=identity, address=("localhost", 5020)) 

Это фрагмент с SIGTERM:

#!/usr/bin/env python 

from pymodbus.server.async import StartTcpServer 

from pymodbus.device import ModbusDeviceIdentification 
from pymodbus.datastore import ModbusSequentialDataBlock 
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext 

import signal 
import sys 

import logging 
logging.basicConfig() 
log = logging.getLogger() 
log.setLevel(logging.DEBUG) 

def signal_term_handler(signal, frame): 
    log.warning('got SIGTERM') 
    sys.exit(0) 

signal.signal(signal.SIGTERM, signal_term_handler) 

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [17]*100), 
    co = ModbusSequentialDataBlock(0, [17]*100), 
    hr = ModbusSequentialDataBlock(0, [17]*100), 
    ir = ModbusSequentialDataBlock(0, [17]*100)) 
context = ModbusServerContext(slaves=store, single=True) 

identity = ModbusDeviceIdentification() 
identity.VendorName = 'Pymodbus' 
identity.ProductCode = 'PM' 
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' 
identity.ProductName = 'Pymodbus Server' 
identity.ModelName = 'Pymodbus Server' 
identity.MajorMinorRevision = '1.0' 

StartTcpServer(context, identity=identity, address=("localhost", 5020)) 
+0

Можете ли вы показать пример программы? Он должен работать так, но если по какой-либо причине ваш обработчик сигналов фактически не выполняется (например, потому что вы заняты циклом или что-то вроде этого), процесс умрет из-за SIGKILL, который отправляется немного позже ... – filmor

+0

Добавлены примеры @filmor, см. вопрос выше – wewa

+0

@wewa, у меня не было проблем с обработчиком сигнала. Проверьте [этот небольшой фрагмент кода] (https://gist.github.com/Borkason/5649fdb41cd76c79787d785e3e951929), он работает красиво. Вы уверены, что проблема в вашем скрипте? – Daniel

ответ

1

В файле службы, используйте Systemd вариант файла сервис "ExecStopPost=<post execution command>", после того, как "ExecStart=<your python script>".

Эта опция "ExecStopPost =" должна использоваться только для выполнения небольшой или незначительной задачи.

Смежные вопросы