2016-01-20 104 views
3

我寫了一個簡單的python程序,並將其作爲systemd服務啓動。我想在systemd關閉這個正在運行的python程序之前做一些事情(例如,將消息寫入日誌文件)。我試圖抓SIGTERM(如此處所述:https://nattster.wordpress.com/2013/06/05/catch-kill-signal-in-python/),但沒有成功。我試過10(如在這篇文章中提到:Doing something before program exit),我也試圖趕上SIGTERM(像這裏描述:https://nattster.wordpress.com/2013/06/05/catch-kill-signal-in-python/),但沒有成功。在systemd停止運行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 =」選項只應用於某些小型或次要任務。

相關問題