python скрипт как демон

Легко настраиваемый python daemon

Дальше я попробую описать логику работы всех трех.

Сразу скажу, что все есть на Гитхабе. Потому как если вы легко читаете питон — читать мой весьма неумелый текст может оказаться гораздо сложнее.

Собственно в первом файлике описывать толком нечего: Это почти неизменные три класса, взятые из этой статьи. Из изменений там только то, что к самому демону был прикреплен класс обработчик сигналов, и добавление сигналов в список обрабатываемых было вкручено в собственно процедуру демонизации.

Вторая часть будет чуть интереснее. Там присутствует три класса:
1) SigFunctionsCon — содержит реакцию на сигналы. При инициализации получает экземпляр демона, чтобы уметь обращаться к его методам. Каждый метод должен соответствовать сигналу, который он обрабатывает названием. Например так:

Внутренние методы и поля могут быть какими угодно.

2)ReactFunctionCon — содержит реакцию на консольные команды. При инициализации так же получает демона. Каждый метод по названию должен соответствовать команде на которую он будет реагировать и может принимать аргументы (то, что собственно идет за командой в командной строке). Например:

3)StatCon — содержит всякие статические настройки демона. На данный момент выглядит так:

Соответственно —
Хелп строка, выводимая при неправильной передаче аргументов в какую-либо функцию (Возможно следует сделать команду хелп по умолчанию, которая выводит это сообщение?).
Метод run — собственно то, для чего все затевалось — то, что демон делает.
Адрес pid файла — для хранения процесса и все такое.
Ввод, вывод, ошибки — логгирование и прочее. По умолчанию отсылается в /dev/null

Центровой скрипт представляет интерес исключительно кодом. В общем говоря он наследует класс демона, собирает все настройки с предыдущего файла и раскладывает их по демону, и принимает команды.

Ну и собственно вопросы:
Что не так, что не очень так?
Как по вашему следует ли как-то приписывать к этому GPL, или не стоит больгеносить, и все это слишком несерьезно?
Достаточно ли адекватно я указал предыдущих авторов?

Источник

xazrad блог

понедельник, 4 февраля 2013 г.

Запуск скрипта Python как Daemon с добавлением в автозагрузку

ОС: Ubuntu.
Для примера «поднимем» web-сервер на Pyhton.
Определим директорию нашего проекта: /home/webserver/

Скрипт для запуска web-сервера /home/webserver/webserver.py

#!/usr/bin/python
#! _*_ coding: UTF-8 _*_
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer

class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(‘Hello, word’)

def start():
server = HTTPServer((»,8082), Handler)
server.serve_forever()

if __name__ == ‘__main__’:
start()

import sys, os, time, atexit
from signal import SIGTERM

class Daemon:
«»»
Родительский класс дeмона
Использование: создайте подкласс и переопределите метод run()
«»»
def __init__(self, pidfile, stdin=’/dev/null’, stdout=’/dev/null’, stderr=’/dev/null’):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile

def daemonize(self):
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
sys.stderr.write(«fork #1 failed: %d (%s)\n» % (e.errno, e.strerror))
sys.exit(1)

# делаем второй fork
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
sys.stderr.write(«fork #2 failed: %d (%s)\n» % (e.errno, e.strerror))
sys.exit(1)

# перенаправление стандартного ввода/вывода
sys.stdout.flush()
sys.stderr.flush()
si = file(self.stdin, ‘r’)
so = file(self.stdout, ‘a+’)
se = file(self.stderr, ‘a+’, 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())

# записываем pidfile
atexit.register(self.delpid)
pid = str(os.getpid())
file(self.pidfile,’w+’).write(«%s\n» % pid)

def delpid(self):
os.remove(self.pidfile)

def start(self):
«»»
Запуск дeмона
«»»
# Проверяем pidfile, чтоб узнать не запущен ли уже процесс
try:
pf = file(self.pidfile,’r’)
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None

if pid:
message = «pidfile %s already exist. Daemon already running?\n»
sys.stderr.write(message % self.pidfile)
sys.exit(1)

# Запуск дeмона
self.daemonize()
self.run()

def stop(self):
«»»
Остановка дeмона
«»»
# Берем pid из pidfile
try:
pf = file(self.pidfile,’r’)
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None

if not pid:
message = «pidfile %s does not exist. Daemon not running?\n»
sys.stderr.write(message % self.pidfile)
return # не считается ошибкой при перезапуске

# Убиваем процесс дeмона
try:
while 1:
os.kill(pid, SIGTERM)
time.sleep(0.1)
except OSError, err:
err = str(err)
if err.find(«No such process») > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print str(err)
sys.exit(1)

def restart(self):
«»»
Перезапуск дeмона
«»»
self.stop()
self.start()

def run(self):
«»»
Вы должны переопределить данный метод в подклассе. Он должен быть вызван
после вызова метода daemonize() в методе start().
«»»

class MyDaemon(Daemon):
def run(self):
webserver.start()

if __name__ == «__main__»:
my_daemon = MyDaemon(‘/var/run/webserver.pid’)

if len(sys.argv) >= 2:
if ‘start’ == sys.argv[1]:
print ‘starting webserver’
my_daemon.start()
elif ‘stop’ == sys.argv[1]:
print ‘stoping webserver’
my_daemon.stop()
elif ‘restart’ == sys.argv[1]:
print ‘restarting webserver’
my_daemon.restart()
else:
print «Unknown command»
sys.exit(2)
sys.exit(0)

Стартовые скрипты при запуске Системы находятся в /etc/init.d
Создаем файл /etc/init.d/webserver со следующим содержимым:

Источник

How to make a Python script run like a service or daemon in Linux

I have written a Python script that checks a certain e-mail address and passes new e-mails to an external program. How can I get this script to execute 24/7, such as turning it into daemon or service in Linux. Would I also need a loop that never ends in the program, or can it be done by just having the code re executed multiple times?

15 Answers 15

You have two options here.

Make a proper cron job that calls your script. Cron is a common name for a GNU/Linux daemon that periodically launches scripts according to a schedule you set. You add your script into a crontab or place a symlink to it into a special directory and the daemon handles the job of launching it in the background. You can read more at Wikipedia. There is a variety of different cron daemons, but your GNU/Linux system should have it already installed.

Use some kind of python approach (a library, for example) for your script to be able to daemonize itself. Yes, it will require a simple event loop (where your events are timer triggering, possibly, provided by sleep function).

I wouldn’t recommend you to choose 2., because you would be, in fact, repeating cron functionality. The Linux system paradigm is to let multiple simple tools interact and solve your problems. Unless there are additional reasons why you should make a daemon (in addition to trigger periodically), choose the other approach.

Also, if you use daemonize with a loop and a crash happens, no one will check the mail after that (as pointed out by Ivan Nevostruev in comments to this answer). While if the script is added as a cron job, it will just trigger again.

Источник

Всегда использую supervisord. Просто отличная штука, ещё и на питоне написанная. Гибкие конфиги, перезапуск при падении. и другие плюшки.

UPD
Как использовать:
1) Ставишь его общесистемно sudo apt-get install supervisor (можно и через пип поставить, но настраивать надо побольше будет).
2) Надо настроить сам супервизор: откуда он будет брать конфиги, какие права нужны и т.д. Если у тебя убунта, то настройки самого супервизора будут в порядке. Они хранятся в /etc/supervisor/supervisord.conf. В этом файле прописано, что настройки для демонов будут читаться из папки /etc/supervisor/conf.d
Если у тебя не убунта, или ты ставил супервизор через пип, то вот стандартный конфиг. Настройки там очевидные
3) Когда супервизор поставлен и настроен, запускай его:

4) Теперь надо сделать конфиг для запуска твоего скрипта. Создаёшь файл в папке с конфигами такого содержания:

Всё! Управлять твоими демонами можно через команду supervisorctl. Сперва надо перепрочитать конфиг, потом стартануть приложение:

Можно опустить ОТОБРАЖАЕМОЕ_ИМЯ, тогда команда будет применена ко всем.
Также ты можешь запустить CLI, если введёшь supervisorctl без параметров. Там по табу смотри команды.
Читай этот раздел, для понимания конфигов запускаемых приложений.

python скрипт как демон

python скрипт как демон

Для запуска при старте системы надо написать скрипт для старта вашей программы. В теории можно и на bash забацать демона. Если вам интересен этот вариант, я дам пример скрипта.

python скрипт как демон

python скрипт как демон

Давайте я сделаю небольшой итог.

сделать свой скрипт нормальным демоном или использовать слд варианты в linux.

Использовать /etc/rc.local для запуска программы в фоновом режиме (&) с перенаправленными потоками ввода/вывода. Можно воспользоваться командой nohup.

Использовать inittab и указать уровень запуска программы (не рекомендую)

Написать скрипт на bash, позволяющий запускать/останавливать/перезапускать программу как демона, а также получать информацию о её состоянии.

python скрипт как демон

python скрипт как демон

Т.е. отпадает необходимость вручную писать баш-скрипты, которые хранят пид, запускают программу, перенаправляют вывод и т.д. Это всё просто автоматизированно и очень удобно. Ты просто описываешь конфиг для каждой задачи, требующей демонизации, читаешь его (для supervisord есть удобный CLI), запускаешь. Далее, ты можеш остановить отдельную задачу, посмотреть статус, и т.д.

python скрипт как демон

python скрипт как демон

python скрипт как демон

В техническом смысле демоном считается процесс, который не имеет управляющего терминала.
Это с вики. Можешь ещё на английской прочитать, как демоны создавать. В некоторых дистрах есть start-stop-daemon.

Почему я в скрипте это «зациклел»
Ты зациклил только потому, что сама программа, которую ты запускаешь, делает какое-то действие и выходит. По-сути, ты написал новую программу на баше, которая в цикле выполняет какой-то процесс, анализирует его вывод и спит некоторое время, после чего по-новой.
Так вот, если сама программа сама запускается в бесконечном цикле, то вручную зацикливать не нужно. Если просто запустить такую программу, то терминал будет занят, в нём будет вывод такой программы. Если запустить в фоне, то процесс всё равно будет привязан к терминалу, поэтому при закрытии терминала такой процесс будет завершён. Если же отсоединить такой процесс, то получится как раз демон.

и как бы мне помог ваш супервизор в данной ситуации.
Очень просто: весь твой бесконечный цикл надо вынести в bash-скрипт, а в супервизоре в настройках надо просто указать нужную команду.

Источник

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

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

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

15 ответов

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

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

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

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

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

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

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

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

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

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

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

фактически стать демоном процесс, не приводящий к зомби

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

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

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

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

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

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

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

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

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 и использовал следующий код:

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

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

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

еще одну вещь, чтобы думать о том, когда daemonizing в Python:

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

Я изменил несколько строк в примере кода Сандера Марешаля (упомянутом @JeffBauer в принято отвечать), чтобы добавить quit() метод, который выполняется до остановки демона. Иногда это очень полезно.

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

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

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

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

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

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *