我有一个python脚本,我希望在daemontools下作为守护进程运行。通常,在deamontools下运行的服务在前台运行,如果它停止运行,daemontools将重新启动它。该服务还应处理here所述的信号。
我的程序捕获SIGINT
和SIGALRM
,当收到信号后,程序会退出。
当从命令行运行程序并且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()
答案 0 :(得分:3)
我使用以下运行脚本在daemontools下运行程序
#!/bin/sh exec 2>&1 /usr/bin/python /home/test/sigtest.py
这是你的错误。你正在分配一个子进程来运行python程序。停止你的守护进程分叉。守护进程不需要也不应该在子进程中运行,无论是在daemontools下运行,daemontools-encore,runit,s6,perp,甚至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