我编写了一个简单的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))
答案 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