daemontools下的Python脚本没有获得信号15

时间:2014-02-01 14:28:30

标签: python daemon

我有一个python脚本,我希望在daemontools下作为守护进程运行。通常,在deamontools下运行的服务在前台运行,如果它停止运行,daemontools将重新启动它。该服务还应处理here所述的信号。

我的程序捕获SIGINTSIGALRM,当收到信号后,程序会退出。

当从命令行运行程序并且kill -1 <pid>kill -15 <pid>发出信号时,将运行信号处理程序,这会导致程序退出,并打印相应的日志。

但是当程序在daemontools下运行并执行svc -d /service/myrogram时,程序既不退出也不打印日志。

我正在使用以下run脚本在daemontools下运行该程序

#!/bin/sh
exec 2>&1
/usr/bin/python /home/test/sigtest.py

我想知道为什么kill -15 <pid>有效,而svc -d /service/myrogram似乎没有将信号传递给python程序。

我正在使用的python脚本是:

from pyudev import Context, Monitor, MonitorObserver
import signal, sys, time

def print_device_event(device):
    print ('New event - {0.action}: {0.device_path}'.format(device))

if __name__ == '__main__':
    context = Context()
    monitor = Monitor.from_netlink(context)
    observer = MonitorObserver(monitor, callback=print_device_event, name='monitor-observer')
    print ("Processing started")
    observer.start()
    def handler(signum, frame):
        print("Received Signal: %d"%signum)
        observer.send_stop()
        print("Exiting.")
    signal.signal(signal.SIGTERM, handler)
    signal.signal(signal.SIGHUP, handler)

    try:
        while observer.is_alive():
            observer.join(timeout=1.0)
    except (KeyboardInterrupt, SystemExit):
        print("Caught KeyboardInterrupt, exiting")
        observer.send_stop()

1 个答案:

答案 0 :(得分:3)

我使用以下运行脚本在daemontools

下运行程序

#!/bin/sh
exec 2>&1
/usr/bin/python /home/test/sigtest.py

这是你的错误。你正在分配一个子进程来运行python程序。停止你的守护进程分叉。守护进程不需要也不应该在子进程中运行,无论是在daemontools下运行,daemontools-encorerunits6perp,甚至systemd

shell的标准操作,记住,是在子进程中分叉和运行命令。

为了获得最佳效果,您应该适应自己使用shell以外的其他东西编写run脚本,链加载守护程序。以下是使用Laurent Bercot's execline代替run作为脚本解释器的/bin/sh脚本:

#!/command/execlineb -PW
fdmove -c 2 1
/usr/bin/python /home/test/sigtest.py

execline没有任何非交互式shell所做的任何开销,包括解析启动“rc”文件。它附带了一套有用的链式加载实用程序,用于执行人们可能想要在run脚本中执行的许多操作。

但即使是execline也会在run脚本中执行您不需要的操作。因此-P选项关闭参数推送,它没有run脚本的实用程序。这是您的run脚本使用更简单的脚本解释器,my nosh program

#!/usr/local/bin/nosh
fdmove -c 2 1
/usr/bin/python /home/test/sigtest.py

最后,这是run的{​​{1}}脚本,已更正:

#!/bin/sh
exec 2>&1
exec /usr/bin/python /home/test/sigtest.py

进一步阅读