在systemd停止运行python服务之前做一些事情

时间:2016-01-20 09:38:25

标签: python python-2.7 debian exit systemd

我编写了一个简单的python程序并将其作为systemd服务启动。我想在systemd关闭这个正在运行的python程序之前做点什么(例如写消息到logfile)。

我尝试atexit(就像在这篇文章中提到的那样:Doing something before program exit),我也尝试抓住SIGTERM(如此处所述:https://nattster.wordpress.com/2013/06/05/catch-kill-signal-in-python/),但没有成功。< / p>

我正在使用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))

2 个答案:

答案 0 :(得分:1)

在服务文件中,在“ExecStopPost=<post execution command>”之后使用systemd服务文件选项“ExecStart=<your python script>”。

此“ExecStopPost =”选项仅应用于某些小型或次要任务。

答案 1 :(得分:1)

这对我有用,并且我根本不需要更改atexit.register()或.py的其余部分:

将SIGINT添加到我的systemd foo.service文件中:

KillSignal=SIGINT
ExecStopPost=/bin/echo "my_service stopped"
TimeoutStopSec=3