Как создать демона в Python?


поиск в Google показывает фрагменты кода x2. Первый результат-это этот код рецепт который имеет много документации и объяснений, а также некоторые полезные обсуждения ниже.

, еще один пример кода, хотя и не содержит так много документации, включает в себя пример кода для передачи команд, таких как start, stop и restart. Он также создает PID-файл, который может быть удобен для проверки, если демон уже есть бег и т. д.

эти примеры оба объясняют, как создать демона. Есть ли какие-то дополнительные вещи, которые необходимо учитывать? Один пример лучше другого, и почему?

15 224

15 ответов:

текущее решение

при использовании PEP 3143 (стандартная библиотека процессов демона) теперь доступен в качестве python-daemon.

исторические ответа

Сандер предводителя пример кода превосходит оригинал, который был первоначально опубликован в 2004 году. Однажды я внес демонизатор для Pyro, но, вероятно, использовал бы код Сандера, если бы мне пришлось это сделать.

здесь многие неудобные вещи чтобы заботиться о том, когда становится хорошо себя ведет демон процесс:

  • предотвращение дампов ядра (многие демоны работают как root, а дампы ядра могут содержать конфиденциальную информацию)

  • вести себя правильно внутри chroot тюрьма

  • установите UID, GID, рабочий каталог, umask и другие параметры процесса соответствующим образом для использования дело

  • отказаться от повышенных suid,sgid льготы

  • закрыть все открытые файловые дескрипторы, с исключениями в зависимости от использования

  • вести себя правильно, если запущен внутри уже отсоединенного контекста, например init,inetd и т. д.

  • настройка обработчиков сигналов для разумного поведения демона, но и с конкретными обработчиками, определяемыми использованием дело

  • перенаправление стандартных потоков stdin,stdout,stderr поскольку процесс демона больше не имеет управляющего терминала

  • обрабатывать PID-файл в качестве совместной консультативной блокировки, которая является песня сама по себе со многими противоречивыми, но правильными способами поведения

  • разрешить правильную очистку при завершении процесса

  • на самом деле стать демоном процесс без приведения к зомби

некоторые из них являются стандартный, как описано в канонической литературе Unix (расширенное программирование в среде UNIX, покойный У. Ричард Стивенс, Аддисон-Уэсли, 1992). Другие, такие как перенаправление потока и обработка файлов PID, are обычное поведение большинство пользователей демонов ожидали бы, но это меньше стандартизированный.

все они покрыты PEP 3143 спецификация "стандартная библиотека процессов демона". Элемент python-daemon эталонная реализация работает на Python 2.7 или более поздней версии и Python 3.2 или более поздней версии.

вот мой основной демон Python "Howdy World", с которого я начинаю, когда разрабатываю новое приложение демона.

#!/usr/bin/python
import time
from daemon import runner

class App():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/tmp/foo.pid'
        self.pidfile_timeout = 5
    def run(self):
        while True:
            print("Howdy!  Gig'em!  Whoop!")
            time.sleep(10)

app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

обратите внимание, что вам понадобится python-daemon библиотека. Вы можете установить его по адресу:

pip install python-daemon

тогда просто начните с ./howdy.py start и с ./howdy.py stop.

Примечание python-daemon пакет, который решает много проблем за демонов из коробки.

среди других функций он позволяет (из описания пакета Debian):

  • отсоедините процесс в его собственную группу процессов.
  • установить условия проведения процесса, соответствующего для запуска в chroot-окружении.
  • отказаться от привилегий suid и sgid.
  • закрыть все открытые дескрипторы файлов.
  • изменить каталог, uid, gid и umask.
  • установить соответствующие обработчики сигналов.
  • откройте новые файловые дескрипторы для stdin, stdout и stderr.
  • управление указанным файлом блокировки PID.
  • функции очистки регистра для обработки на выходе.

альтернатива -- создать нормальную, не демонизированную программу Python, а затем внешне демонизировать ее с помощью supervisord. Это может сэкономить много головной боли,и * nix - и язык-портативный.

вероятно, это не прямой ответ на вопрос, но systemd можно использовать для запуска вашего приложения в качестве демона. Вот пример:

[Unit]
Description=Python daemon
After=syslog.target
After=network.target

[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

Я предпочитаю этот метод, потому что большая часть работы выполняется за вас, а затем ваш сценарий демона ведет себя аналогично остальной части вашей системы.

- Orby

YapDi это относительно новый модуль python, который появился в Hacker News. Выглядит довольно полезно, может использоваться для преобразования скрипта python в режим демона изнутри скрипта.

поскольку python-daemon еще не поддерживает python 3.x, и из того, что можно прочитать в списке рассылки, это может никогда не будет, я написал новую реализацию PEP 3143: pep3143daemon

pep3143daemon должен поддерживать по крайней мере python 2.6, 2.7 и 3.x

Он также содержит класс PidFile.

библиотека зависит только от стандартной библиотеки и от шести модулей.

его можно использовать как падение в замене для питон-демон.

здесь документация.

боюсь, что модуль демона, упомянутый @Dustin, не работал для меня. Вместо этого я установил python-daemon и использовал следующий код:

# filename myDaemon.py
import sys
import daemon
sys.path.append('/home/ubuntu/samplemodule') # till __init__.py
from samplemodule import moduleclass 

with daemon.DaemonContext():
    moduleclass.do_running() # I have do_running() function and whatever I was doing in __main__() in module.py I copied in it.

работает легко

> python myDaemon.py

просто для полноты вот содержимое каталога samplemodule

>ls samplemodule
__init__.py __init__.pyc moduleclass.py

содержание moduleclass.py может быть

class moduleclass():
    ...

def do_running():
    m = moduleclass()
    # do whatever daemon is required to do.

эта функция преобразует приложение в демон:

import sys
import os

def daemonize():
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #1 failed: {0}\n'.format(err))
        sys.exit(1)
    # decouple from parent environment
    os.chdir('/')
    os.setsid()
    os.umask(0)
    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #2 failed: {0}\n'.format(err))
        sys.exit(1)
    # redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

еще одна вещь, о которой нужно думать при демонизации в python:

Если вы используете python лесозаготовки и вы хотите продолжать использовать его после демонизации, обязательно позвоните close() на обработчиках (особенно обработчики файлов).

Если вы этого не сделаете, обработчик все равно может думать, что у него есть открытые файлы, и ваши сообщения просто исчезнут - другими словами, убедитесь, что регистратор знает, что его файлы закрыты!

это предполагает, когда вы daemonise вы закрываете все открытые файловые дескрипторы без разбора - вместо этого вы можете попробовать закрыть все, кроме файлов журнала (но обычно проще закрыть все, а затем снова открыть те, которые вы хотите).

Я изменил несколько строк в примере кода Sander Marechal (упоминается @JeffBauer в принято отвечать), чтобы добавить quit() метод, который выполняется до остановки демона. Это иногда очень полезно.

здесь.

примечание: Я не использую модуль "python-daemon", потому что документация все еще отсутствует (см. Также многие другие вопросы SO) и довольно неясна (как правильно запустить/остановить демон из командная строка с этим модулем?)

после нескольких лет и многих попыток, теперь я понимаю, что есть лучший способ, чем желание запустить, остановить, перезапустить демон непосредственно из Python: используйте инструменты ОС вместо этого!

короче, вместо того, чтобы делать python myapp start и python myapp stop, Я делаю это, чтобы запустить приложение:

screen -S myapp python myapp.py    
CTRL+A, D to detach

или screen -dmS myapp python myapp.py до запустите и отсоедините его одной командой.

затем:

screen -r myapp

чтобы снова подключиться к этому терминалу. Оказавшись в терминале, можно используйте CTRL+C, чтобы остановить его.

самый простой способ создать демон с Python-это использовать Twisted событийных рамок. Он обрабатывает все вещи, необходимые для демонизации Для вас. Он использует Шаблон Реактор для обработки одновременных запросов.

80% времени, когда люди говорят "демон", они только хотят сервер. Поскольку вопрос совершенно неясен по этому вопросу,трудно сказать, какова возможная область ответов. Поскольку сервер адекватен, начните там. Если фактический "демон" действительно необходим (это редко), прочитайте на nohup как способ демонизации сервер.

до тех пор, пока фактический демон не потребуется, просто напишите простой сервер.

также Посмотри WSGI ссылка реализация.

также Посмотри простой HTTP-сервер.