你好,

我试图让python脚本在(ubuntu)linux上作为服务(守护进程)运行.

在网络上存在以下几种解决方案:

http://pypi.python.org/pypi/python-daemon/

一个行为良好的Unix守护进程很难正确运行,但每个守护程序所需的步骤基本相同.DaemonContext实例保存程序的行为和配置的进程环境;将实例用作上下文管理器以进入守护程序状态.

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

然而,由于我想将我的python脚本与UbuntuLinux集成在一起,我的解决方案是结合使用init.d脚本

#!/bin/bash

WORK_DIR="/var/lib/foo"
DAEMON="/usr/bin/python"
ARGS="/opt/foo/linux_service.py"
PIDFILE="/var/run/foo.pid"
USER="foo"

case "$1" in
  start)
    echo "Starting server"
    mkdir -p "$WORK_DIR"
    /sbin/start-stop-daemon --start --pidfile $PIDFILE \
        --user $USER --group $USER \
        -b --make-pidfile \
        --chuid $USER \
        --exec $DAEMON $ARGS
    ;;
  stop)
    echo "Stopping server"
    /sbin/start-stop-daemon --stop --pidfile $PIDFILE --verbose
    ;;
  *)
    echo "Usage: /etc/init.d/$USER {start|stop}"
    exit 1
    ;;
esac

exit 0

在python中:

import signal
import time
import multiprocessing

stop_event = multiprocessing.Event()

def stop(signum, frame):
    stop_event.set()

signal.signal(signal.SIGTERM, stop)

if __name__ == '__main__':
    while not stop_event.is_set():
        time.sleep(3)

我现在的问题是,这种方法是否正确.我需要处理其他信号吗?它会是一个"行为良好的Unix守护进程"吗?

推荐答案

假设你的守护进程有某种持续运行的方式(一些事件循环,扭曲,等等),你可以try 使用upstart.

下面是一个假设Python服务的upstart配置示例:

description "My service"
author  "Some Dude <blah@foo.com>"

start on runlevel [234]
stop on runlevel [0156]

chdir /some/dir
exec /some/dir/script.py
respawn

如果您将其另存为脚本.conf到/etc/init你只需做一次

$ sudo initctl reload-configuration
$ sudo start script

你可以用stop script来阻止它.上面upstart conf所说的是在重新启动时启动这个服务,如果它死了也重新启动它.

至于信号处理——你的过程应该自然地响应SIGTERM.默认情况下,除非您专门安装了自己的信号处理程序,否则应该处理这个问题.

Linux相关问答推荐

GO:当使用NewManager调用创建cgroup时,权限被拒绝

在Bluez/Linux中,周期性与连续蓝牙设备发现的已知缺陷是什么?

为什么我们不能使用${$#}来获取传递给shell 脚本的最后一个参数?

条件句if的正确写法是怎样的?

奇怪的 Bash 脚本行为

Linux 中大型 TSV 的条件编辑

计算与文件第一列对应的第二列中的字符串出现次数

AWK 命令根据另一列中相同的值获取列中的不同值

awk 使用动态列号

为什么组合的查找和重命名命令在 bash shell 下不能按预期工作?

如何更改文件的上次访问/修改/更改日期?

sed 命令在 gitlab runner 上无法正确执行

使用 gdb 将地址转换为行

应用程序如何在运行时解析为不同版本的共享库?

优雅地杀死在 Linux 上运行的 .NET Core 守护进程

如何在 shell 脚本中向文件中添加一行?

用于提取 IP 地址的 Linux bash 脚本

rename() 是原子的吗?

如何使用cp从不同目录复制多个文件?

Linux 上的最大文件/目录数?